动态添加项目到ListView

时间:2012-09-02 22:53:00

标签: android listview

我正在使用android中的ListView。我知道如何使用常用方式填写android ListView。但是假设我们有一个如下所示的类,其中包含两个TextView,一个Button和一个ProgressBar。我已声明RelativeLayout并成功添加了此布局中的所有视图。 (使用setContentView(new ListViewItem(this).getLayout());测试,基本上没问题。)

public class ListViewItem {
    public ListViewItem(Context context) {
        this.M_speedTextView = new TextView(context);
        this.M_nameTextView = new TextView(context);
        this.M_progressBar = new ProgressBar(context, null,
                android.R.attr.progressBarStyleHorizontal);
        this.M_activityButton = new Button(context);
        this.M_layout = new RelativeLayout(context);

        this.M_speedTextView.setId(new Random().nextInt());
        this.M_nameTextView.setId(new Random().nextInt());
        this.M_progressBar.setId(new Random().nextInt());
        this.M_activityButton.setId(new Random().nextInt());

        this.M_layout.setId(new Random().nextInt());
    }

    public void setSpeed(int speed) {
        this.M_speedTextView.setText(Integer.toString(speed));
    }

    public void setName(String name) {
        this.M_nameTextView.setText(name);
    }

    public void setProgress(int progress) {
        this.M_progressBar.setProgress(progress);
    }

    public void setButtonText(String text) {
        this.M_activityButton.setText(text);
    }

    public RelativeLayout getLayout() {
        // Layout setting
        this.M_layout.setLayoutParams(new LayoutParams(
                LayoutParams.FILL_PARENT, 50));
        this.M_layout.setBackgroundResource(android.R.color.transparent);

        // Name Text setting
        LayoutParams nameTextParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        nameTextParams.setMargins(5, 10, 0, 0);
        nameTextParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 1);
        nameTextParams.addRule(RelativeLayout.LEFT_OF,
                this.M_speedTextView.getId());

        this.M_nameTextView.setTextSize(15);
        this.M_nameTextView.setText("TextView");
        this.M_nameTextView.setSingleLine();
        this.M_nameTextView.setEllipsize(TruncateAt.END);

        this.M_layout.addView(this.M_nameTextView, nameTextParams);

        // Activity Button setting
        LayoutParams activityParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        activityParams.setMargins(0, 5, 5, 0);
        activityParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
        activityParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1);

        this.M_activityButton.setText("Start");

        this.M_layout.addView(this.M_activityButton, activityParams);

        // ProgressBar setting
        LayoutParams progressParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        progressParams.addRule(RelativeLayout.ALIGN_BOTTOM,
                this.M_activityButton.getId());
        progressParams.addRule(RelativeLayout.ALIGN_LEFT,
                this.M_nameTextView.getId());
        progressParams.addRule(RelativeLayout.BELOW,
                this.M_nameTextView.getId());
        progressParams.addRule(RelativeLayout.LEFT_OF,
                this.M_activityButton.getId());

        this.M_layout.addView(this.M_progressBar, progressParams);

        // Speed TextView setting
        LayoutParams speedParam = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        speedParam.addRule(RelativeLayout.ALIGN_BASELINE,
                this.M_nameTextView.getId());
        speedParam.addRule(RelativeLayout.ALIGN_BOTTOM,
                this.M_nameTextView.getId());
        speedParam.addRule(RelativeLayout.LEFT_OF,
                this.M_activityButton.getId());

        this.M_speedTextView.setText("0 KiB/s");
        this.M_speedTextView.setTextSize(15);

        this.M_layout.addView(this.M_speedTextView, speedParam);

        return this.M_layout;
    }

    TextView M_speedTextView;
    TextView M_nameTextView;
    ProgressBar M_progressBar;
    Button M_activityButton;
    RelativeLayout M_layout;
}

现在,我创建了一个ListViewItem数组,我想将这些数组项添加到ListView中。 (我们可以使用ListViewItem类的getLayout()方法获取包含所有这些视图的布局)。

请注意,我想动态添加这些视图。不使用常用方法填写。任何人都可以指导我如何达到这个目标?

编辑常用方法:将xml文件声明为listViewItem,对其进行膨胀和使用子项,并以getView方法返回。

编辑我目前使用的适配器类和LogCat错误:

public class ListViewAdapter extends BaseAdapter {
    private ArrayList<ListViewItem> M_items;

    public ListViewAdapter(ArrayList<ListViewItem> items) {
        this.M_items = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return this.M_items.get(position).getLayout();
    }

    @Override
    public int getCount() {
        return this.M_items.size();
    }

    @Override
    public ListViewItem getItem(int position) {
        return this.M_items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return this.M_items.get(position).getId();
    }
}

LogCat错误:

09-03 03:56:23.359: E/AndroidRuntime(9415): FATAL EXCEPTION: main
09-03 03:56:23.359: E/AndroidRuntime(9415): java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.ListView.measureScrapChild(ListView.java:1189)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1272)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.ListView.onMeasure(ListView.java:1181)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.RelativeLayout.measureChild(RelativeLayout.java:566)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:381)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:531)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewRoot.performTraversals(ViewRoot.java:845)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1866)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.os.Looper.loop(Looper.java:130)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.app.ActivityThread.main(ActivityThread.java:3687)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at java.lang.reflect.Method.invokeNative(Native Method)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at java.lang.reflect.Method.invoke(Method.java:507)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at dalvik.system.NativeStart.main(Native Method)

提前致谢:)

3 个答案:

答案 0 :(得分:1)

如果我不知道我在说什么,请原谅我。我偶然发现这一点,试图学习这些东西。也许这与你的困境有关。

http://p-xr.com/android-tutorial-dynamicaly-load-more-items-to-the-listview-never-ending-list/

答案 1 :(得分:1)

通常,列表适配器使用某种数据结构或容器来存储其对象。如果需要添加新元素,请先将其添加到容器中,然后调用

adapter.notifyDataSetChanged();

让它知道它的数据已经改变,需要更新。

这只是一个引导您朝着正确方向前进的小例子。我希望你会发现它很有用。

定义ListActivity:

package com.myapp.listviewexample;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ListViewExampleActivity extends ListActivity {

    static final String[] COUNTRIES = new String[] {
        "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
        "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
        "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan"
      };


    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      //setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));
      final MyListAdapter adapter = new MyListAdapter(this, COUNTRIES);
      setListAdapter(adapter);

      ListView lv = getListView();
      //lv.setTextFilterEnabled(true);

      lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {

            adapter.removeItem(position);
            adapter.notifyDataSetChanged();
          // When clicked, show a toast with the TextView text
          Toast.makeText(getApplicationContext(), ((TextView) view).getText() + " removed",
              Toast.LENGTH_SHORT).show();
        }
      });
    }

}

定义列表适配器:

package com.myapp.listviewexample;

import java.util.ArrayList;
import java.util.Arrays;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyListAdapter extends BaseAdapter {

    private ArrayList<String> items;
    private Context mContext;

    public MyListAdapter(Context c, String[] countries) {
        items = new ArrayList<String>(Arrays.asList(countries));
        mContext = c;
        Log.i("MyListAdapter", "countries.length == items.size() " + (countries.length == items.size()));
    }

    public int getCount() {
        return items.size();
    }

    public Object getItem(int position) {
        return items.get(position);
    }

    public long getItemId(int position) { 
        return position;
    }

    public void removeItem(int position) {
        items.remove(position);
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = li.inflate(R.layout.list_item, null);
        } else {
            view = convertView;
        }

        TextView tv = (TextView) view;//.findViewById(R.id.text_view_item);
        tv.setText(items.get(position));

        return view;
    }

}

考虑使用适配器的ViewHolder模式,以避免不必要的视图膨胀。这篇文章可能有所帮助: How can I make my ArrayAdapter follow the ViewHolder pattern?

定义list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text_view_item"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>

答案 2 :(得分:0)

尝试使用此类而不是发布的ListViewItem类:

public class ListViewItem extends RelativeLayout {
    @SuppressWarnings("deprecation")
    public ListViewItem(Context context) {
        super(context);

        this.M_speedTextView = new TextView(context);
        this.M_nameTextView = new TextView(context);
        this.M_progressBar = new ProgressBar(context, null,
                android.R.attr.progressBarStyleHorizontal);
        this.M_activityButton = new Button(context);

        this.M_speedTextView.setId(new Random().nextInt());
        this.M_nameTextView.setId(new Random().nextInt());
        this.M_progressBar.setId(new Random().nextInt());
        this.M_activityButton.setId(new Random().nextInt());

        this.setId(new Random().nextInt());

        /***************************************************************/
        this.setLayoutParams(new AbsListView.LayoutParams(
                LayoutParams.FILL_PARENT, 50));
        this.setBackgroundResource(android.R.color.transparent);

        // Name Text setting
        LayoutParams nameTextParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        nameTextParams.setMargins(5, 10, 0, 0);
        nameTextParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 1);
        nameTextParams.addRule(RelativeLayout.LEFT_OF,
                this.M_speedTextView.getId());

        this.M_nameTextView.setTextSize(15);
        this.M_nameTextView.setText("TextView");
        this.M_nameTextView.setSingleLine();
        this.M_nameTextView.setEllipsize(TruncateAt.END);

        this.addView(this.M_nameTextView, nameTextParams);

        // Activity Button setting
        LayoutParams activityParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        activityParams.setMargins(0, 5, 5, 0);
        activityParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
        activityParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1);

        this.M_activityButton.setText("Start");

        this.addView(this.M_activityButton, activityParams);

        // ProgressBar setting
        LayoutParams progressParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        progressParams.addRule(RelativeLayout.ALIGN_BOTTOM,
                this.M_activityButton.getId());
        progressParams.addRule(RelativeLayout.ALIGN_LEFT,
                this.M_nameTextView.getId());
        progressParams.addRule(RelativeLayout.BELOW,
                this.M_nameTextView.getId());
        progressParams.addRule(RelativeLayout.LEFT_OF,
                this.M_activityButton.getId());

        this.addView(this.M_progressBar, progressParams);

        // Speed TextView setting
        LayoutParams speedParam = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        speedParam.addRule(RelativeLayout.ALIGN_BASELINE,
                this.M_nameTextView.getId());
        speedParam.addRule(RelativeLayout.ALIGN_BOTTOM,
                this.M_nameTextView.getId());
        speedParam.addRule(RelativeLayout.LEFT_OF,
                this.M_activityButton.getId());

        this.M_speedTextView.setText("0 KiB/s");
        this.M_speedTextView.setTextSize(15);

        this.addView(this.M_speedTextView, speedParam);
    }

    public void setSpeed(int speed) {
        this.M_speedTextView.setText(Integer.toString(speed));
    }

    public void setName(String name) {
        this.M_nameTextView.setText(name);
    }

    public void setProgress(int progress) {
        this.M_progressBar.setProgress(progress);
    }

    public void setButtonText(String text) {
        this.M_activityButton.setText(text);
    }

    TextView M_speedTextView;
    TextView M_nameTextView;
    ProgressBar M_progressBar;
    Button M_activityButton;
}

getView适配器方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return this.M_items.get(position);
}