动态添加自定义行到列表视图

5
通过参考这个,我创建了以下内容: main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/addBtn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="addItems"
        android:text="Add New Item" />

    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:drawSelectorOnTop="false" />

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity {
    ListView list;   
    ArrayList<String> listItems = new ArrayList<String>();    
    ArrayAdapter<String> adapter;   
    int clickCounter = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        list = (ListView) findViewById(R.id.list);
        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, listItems);
        list.setAdapter(adapter);

        list.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                String item = list.getItemAtPosition(position).toString();
                Log.i("MainActivity", "Selected = " + item);
            }
        });
    }

    public void addItems(View v) {
        listItems.add("Clicked : " + clickCounter++);
        adapter.notifyDataSetChanged();
    }
}

目前看来一切都很顺利。但是根据需求,我的每个 listview 行 不仅仅只是一个字符串。相反,它将是由图像视图和存储在 row.xml 中的文本视图组成的视图集合。

现在我的问题是:

  • 什么将取代 adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listItems); ?将是 adapter = new ArrayAdapter<String>(this,R.layout.row, listItems); 吗?

  • 如何引用每一行的图像视图和文本视图?如何设置和获取它们的数据?如何识别其点击事件?

  • 使用 Adapter 是否必须?或者能否不使用?

任何帮助都将受到赞赏。


创建自己的自定义适配器并覆盖getView()方法以填充所需的行布局。 - Houcine
3个回答

4
按照要求翻译如下:

但是根据要求,我的每个列表视图行不仅仅是一个字符串。相反,它将是一个包含在row.xml中存储的imageview和textviews的视图集合。

=> 您显示的ListView正在使用普通适配器。如果您希望您的项目包含多个视图,例如Imageview、Textview或任何视图,则必须通过扩展BaseAdapter或ArrayAdapter来定义自定义适配器类。

adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,listItems);将被替换为什么?adapter = new ArrayAdapter(this,R.layout.row,listItems);吗?

=> 在这种情况下,ArrayAdapter将无法工作,因为您的行xml布局可能包含不同的视图,例如ImageView、TextView、Button或任何其他小部件。因此,我建议您定义自己的适配器类,在其中必须覆盖getView()方法。

如何引用每行的imageview和textviews?如何从它们设置和获取数据?如何识别它们的单击事件?

=> 如上所述,一旦您定义了自定义适配器类,您将不得不覆盖getView()方法,在其中可以查找行xml布局文件的任何视图,引用它并设置/显示您想要的任何数据。

使用适配器是必须的吗?还是我可以不用它?

=> 是的,它是必须的,没有适配器,您将无法在数据绑定的小部件(例如GridView、ListView、Spinner、Gallery等)中显示。

自定义适配器示例:

  1. 我的ListView演讲
  2. http://www.vogella.com/articles/AndroidListView/article.html

@GAMA 欢迎!获取被点击的对象/项目并从该对象中提取您想要的任何详细信息。 - Paresh Mayani

1

这是我的项目代码:

假设您的列表有两个文本字段和一个ImageView,就像下面的"row.xml"文件一样。请将此文件复制到您的res文件夹中。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

    <TextView
        android:id="@+id/row_q"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:text="Solve[{x^2==4,x+y^2==6},{x,y}]"
        android:textAppearance="@android:style/TextAppearance.Small"
        android:textStyle="bold|italic" />

<TextView
    android:id="@+id/row_a"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/AliceBlue"
    android:gravity="center_vertical"
    android:paddingLeft="10dp"
    android:textAppearance="@android:style/TextAppearance.Small" />

<ImageView
    android:id="@+id/row_a_math"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"/>

<LinearLayout
android:id="@+id/graph_layout"
android:layout_width="match_parent"
android:layout_height="200dp"
android:visibility="gone" >        
</LinearLayout>

在您的活动中创建以下类来存储这些数据。
private class QuesSolnInfo { 
    public String ques; 
    public String ans; 
    public Bitmap ans_b; 

    public QuesSolnInfo(String ques, String ans, Bitmap ans_b) { 
        this.ques = ques;  
        this.ans = ans; 
        this.ans_b = ans_b; 
    } 
}

//将以下内容设置为类成员变量

OutputStringArrayAdapter _outputArrayAdapter = null; 
ArrayList<QuesSolnInfo> _outputArrayList = null; 

//在onCreate方法中初始化它们

_outputArrayAdapter = new OutputStringArrayAdapter(getActivity(), _outputArrayList); 
_outputListView.setAdapter(_outputArrayAdapter); 

ArrayAdapter的定义
 protected class OutputStringArrayAdapter extends ArrayAdapter<QuesSolnInfo> { 
    OutputStringArrayAdapter(Context context, ArrayList<QuesSolnInfo> stringArrayList) { 
        super(context, R.layout.list, stringArrayList); 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
        if (convertView == null) { 
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, null); 
        } 

        TextView t_ques = (TextView) convertView.findViewById(R.id.row_q); 
        t_ques.setText(getItem(position).ques); 

        boolean debug = true; 
        TextView t_ans = (TextView) convertView.findViewById(R.id.row_a); 

        String texx = getItem(position).ans;
        t_ans.setText(texx);       

        final ImageView w = (ImageView) convertView.findViewById(R.id.row_a_math); 
        w.setImageBitmap(getItem(position).ans_b); 
        // Show answer in webview               
        return convertView; 
    }        
} 

现在要将任何元素添加到您的列表中,请执行以下操作:

_outputArrayList.add(0, new QuesSolnInfo(string1.string2, bitmap0)); 
_outputArrayAdapter.notifyDataSetChanged(); 

1

以下是基本步骤:

  • 创建一个自定义布局用于行(可能包含一个ImageView和TextView)。在你的示例中使用了android.R.layout.simple_list_item_1,如果你查看Android源代码,你会发现它只是一个带有单个TextView的布局。
  • 创建一个扩展BaseAdapter的类。这将是你的列表适配器。你可以通过构造函数或方法将数据传递给适配器。创建一个字段来存储数据。

现在来回答你的问题:

  • 如何引用每一行的imageview和textviews?
  • 如何设置并获取它们的数据?
  • 如何识别它们的点击事件?

当你扩展BaseAdapter时,你将实现方法public View getView(int position, View convertView, ViewGroup parent)。在这个方法中,你必须填充你的自定义行布局以创建视图。然后使用findViewById方法找到ImageView和TextView。当你有ImageView和TextView时,调用setText或setImageSource来设置你的数据,并为点击事件设置setOnClickListener。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接