【问题标题】:How do you dynamically add elements to a ListView on Android?如何在 Android 上动态地将元素添加到 ListView?
【发布时间】:2011-05-31 06:10:53
【问题描述】:

谁能解释或建议一个在android中动态创建ListView的教程?

这是我的要求:

  • 我应该能够通过按下按钮来动态添加新元素。
  • 应该简单易懂(例如,可能没有任何性能改进或convertView

我知道关于这个主题有很多问题,但我找不到任何可以回答我的问题的问题。

【问题讨论】:

  • Shardul 目前投票率最高的答案被认为是高质量的,用户表示他们认为应该接受它。可以考虑接受吗?

标签: android listview dynamic


【解决方案1】:

首先在项目的res/layout/main.xml 文件夹中创建一个 XML 布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <Button
        android:id="@+id/addBtn"
        android:text="Add New Item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="addItems"/>
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:drawSelectorOnTop="false"
    />
</LinearLayout>

这是一个简单的布局,顶部有一个按钮,底部有一个列表视图。请注意,ListView 的 id 为 @android:id/list,它定义了 ListViewListActivity 可以使用的默认值。

public class ListViewDemo extends ListActivity {
    //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
    ArrayList<String> listItems=new ArrayList<String>();

    //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
    ArrayAdapter<String> adapter;

    //RECORDING HOW MANY TIMES THE BUTTON HAS BEEN CLICKED
    int clickCounter=0;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        adapter=new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            listItems);
        setListAdapter(adapter);
    }

    //METHOD WHICH WILL HANDLE DYNAMIC INSERTION
    public void addItems(View v) {
        listItems.add("Clicked : "+clickCounter++);
        adapter.notifyDataSetChanged();
    }
}

android.R.layout.simple_list_item_1 是 Android 提供的默认列表项布局,您可以将这种常用布局用于不复杂的事情。

listItems 是一个 List,其中包含 ListView 中显示的数据。所有的插入和移除都应该在listItems上完成; listItems 中的更改应反映在视图中。这由ArrayAdapter&lt;String&gt; adapter 处理,应使用以下方式通知:

adapter.notifyDataSetChanged();

适配器使用 3 个参数进行实例化:上下文,可以是您的 activity/listactivity;您的单个列表项的布局;最后是列表,即列表中要显示的实际数据。

【讨论】:

  • 我不明白 ListView 如何将自己附加到我们这里的活动。
  • @Breedly 因为它是 ListActivity 而不是 具有 ListView 布局的 Activity。你不需要找到id的视图。正如您可以在参考文献中看到的那样:ListActivity is an activity that includes a ListView as its only layout element by default. [...] (it) hosts a ListView object。因此,默认情况下,方法(如 setAdapter 等)在类“内部”。
  • 得到正确答案时,让我们表达幸福吧:/
  • 如果ArrayList中的元素比较复杂,比如从网上加载,每个item都包含图片视频之类的,这种做法会不会面临性能问题?
  • 如何在片段中实现它?
【解决方案2】:

而不是

listItems.add("New Item");
adapter.notifyDataSetChanged();

你可以直接调用

adapter.add("New Item");

【讨论】:

  • @gumuruh 适配器本身是可变的,因此我们可以直接添加或删除对象,这些对象将自动调用 listView 的 notifyDatasetChanged() 和 getView()。这减少了额外的代码行。
  • 所以通过添加到适配器自动调用 notifyDatasetChanged() ?哦,我明白了。谢谢@venkat530。但是列表本身呢?我的意思是,如果首先说他创建了一个数组列表,用作适配器的数据容器。现在您只需将一个项目直接添加到适配器而不是数组列表。 arraylist 数据会更新/保持不变吗?
  • @gumuruh 第二个是最佳实践,因为它是同步的。
  • @gumuruh 来自粗略的实验和 ArrayAdapter 源代码 [github.com/android/platform_frameworks_base/blob/master/core/…,看起来底层数据集也将被修改。
  • 我得到了 Shardul 的答案,然后把它弄坏了,不知道如何修复它。一时兴起,我想我会试试这个,瞧,它又能用了!非常感谢!虽然,我不知道它是如何或为什么修复它的。有什么想法吗?
【解决方案3】:

首先,您必须在 activity_main.xml 中添加一个 ListView、一个 EditText 和一个按钮。

现在,在您的 ActivityMain 中:

private EditText editTxt;
private Button btn;
private ListView list;
private ArrayAdapter<String> adapter;
private ArrayList<String> arrayList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    editTxt = (EditText) findViewById(R.id.editText);
    btn = (Button) findViewById(R.id.button);
    list = (ListView) findViewById(R.id.listView);
    arrayList = new ArrayList<String>();

    // Adapter: You need three parameters 'the context, id of the layout (it will be where the data is shown),
    // and the array that contains the data
    adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, arrayList);

    // Here, you set the data in your ListView
    list.setAdapter(adapter);

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // this line adds the data of your EditText and puts in your array
            arrayList.add(editTxt.getText().toString());
            // next thing you have to do is check if your adapter has changed
            adapter.notifyDataSetChanged();
        }
    });
}

这对我有用,希望对你有帮助

【讨论】:

  • 很好的解释,特别感谢你解释适配器项目——这似乎神奇地出现在其他人的例子中。 :)
  • 这是我找到的最好的例子:)
  • 这个答案满足了这个人的要求。简单干净,没有复杂的改进。最上面的答案其实是介绍了ListActivity,只有大佬知道。我现在唯一的问题是如何向列表中的视图添加可绘制对象和东西。在我看来,我只是在添加字符串。
  • 优化可能是在适配器中创建未命名的列表对象,而不是创建指向列表对象的 16 位指针。创建适配器后不需要它,因为适配器有一个 add 方法。
【解决方案4】:

如果您想在 AppCompatActivity 而不是 ListActivity 中使用 ListView,您可以执行以下操作(修改 @Shardul 的答案):

public class ListViewDemoActivity extends AppCompatActivity {
    //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
    ArrayList<String> listItems=new ArrayList<String>();

    //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
    ArrayAdapter<String> adapter;

    //RECORDING HOW MANY TIMES THE BUTTON HAS BEEN CLICKED
    int clickCounter=0;
    private ListView mListView;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_list_view_demo);

        if (mListView == null) {
            mListView = (ListView) findViewById(R.id.listDemo);
        }

        adapter=new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,
                listItems);
        setListAdapter(adapter);
    }

    //METHOD WHICH WILL HANDLE DYNAMIC INSERTION
    public void addItems(View v) {
        listItems.add("Clicked : "+clickCounter++);
        adapter.notifyDataSetChanged();
    }

    protected ListView getListView() {
        if (mListView == null) {
            mListView = (ListView) findViewById(R.id.listDemo);
        }
        return mListView;
    }

    protected void setListAdapter(ListAdapter adapter) {
        getListView().setAdapter(adapter);
    }

    protected ListAdapter getListAdapter() {
        ListAdapter adapter = getListView().getAdapter();
        if (adapter instanceof HeaderViewListAdapter) {
            return ((HeaderViewListAdapter)adapter).getWrappedAdapter();
        } else {
            return adapter;
        }
    }
}

在你的布局中,你可以使用android:id="@android:id/list"而不是android:id="@+id/listDemo"

所以现在您可以在普通的AppCompatActivity 中添加一个ListView

【讨论】:

    【解决方案5】:

    MainActivity.java 文件的代码。

    public class MainActivity extends Activity {
    
        ListView listview;
        Button Addbutton;
        EditText GetValue;
        String[] ListElements = new String[] {
            "Android",
            "PHP"
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            listview = (ListView) findViewById(R.id.listView1);
            Addbutton = (Button) findViewById(R.id.button1);
            GetValue = (EditText) findViewById(R.id.editText1);
    
            final List < String > ListElementsArrayList = new ArrayList < String >
                (Arrays.asList(ListElements));
    
    
            final ArrayAdapter < String > adapter = new ArrayAdapter < String >
                (MainActivity.this, android.R.layout.simple_list_item_1,
                    ListElementsArrayList);
    
            listview.setAdapter(adapter);
    
            Addbutton.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
    
                    ListElementsArrayList.add(GetValue.getText().toString());
                    adapter.notifyDataSetChanged();
                }
            });
        }
    }
    

    activity_main.xml 布局文件的代码。

    <RelativeLayout 
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:paddingBottom="@dimen/activity_vertical_margin"
      android:paddingLeft="@dimen/activity_horizontal_margin"
      android:paddingRight="@dimen/activity_horizontal_margin"
      android:paddingTop="@dimen/activity_vertical_margin"
      tools:context="com.listviewaddelementsdynamically_android_examples
        .com.MainActivity" >
    
      <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
        android:layout_centerHorizontal="true"
        android:text="ADD Values to listview" />
    
      <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="26dp"
        android:ems="10"
        android:hint="Add elements listView" />
    
      <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_centerHorizontal="true" >
      </ListView>
    
    </RelativeLayout>
    

    屏幕截图

    【讨论】:

      【解决方案6】:

      简短的回答:当您创建一个 ListView 时,您将一个对数据的引用传递给它。 现在,无论何时更改此数据,它都会影响列表视图,从而在您调用 adapter.notifyDataSetChanged(); 之后将项目添加到其中。

      如果您使用的是 RecyclerView,请仅更新最后一个元素(如果您已将其添加到 obj 列表的末尾)以节省内存:mAdapter.notifyItemInserted(mItems.size() - 1);

      【讨论】:

        【解决方案7】:
                This is the simple answer how to add datas dynamically in listview android kotlin
        
        
        class MainActivity : AppCompatActivity(){
                
                    var listItems = arrayListOf<String>()
                    val array = arrayOf("a","b","c","d","e")
                    var listView: ListView? = null
            
                    private lateinit var adapter: listViewAdapter
                
                    override fun onCreate(savedInstanceState: Bundle?) {
                        super.onCreate(savedInstanceState)
                        setContentView(R.layout.scrollview_layout)
                
                        listItems.add("a")
                        listItems.add("b")
                        listItems.add("c")
                        listItems.add("d")
                        listItems.add("e")
                
                        //if you want to add array items to a list you can try this for each loop
                        for(items in array)
                            listItems.add(items)
                        
                        //check the result in console
                        Log.e("TAG","listItems array: $listItems")
            
                    adapter = ListViewAdapter()
                    adapter.updateList(listItems)
                    adapter.notifyDataSetChanged()
                
                    }
                }
        
        
        //Here is the adapter class
            class ListviewAdapter : BaseAdapter(){
            
            private var itemsList = arrayListOf<String>()
            
            override fun getView(position: Int, container: View?, parent: ViewGroup?): View {
                    var view  = container
                    val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
                    if (view == null)
                        view = inflater.inflate(R.layout.list_pc_summary, parent, false)
            
            return view
            }
            
            override fun getItem(position: Int): Any  = itemsList[position]
            
            override fun getItemId(position: Int): Long = position.toLong()
            
            override fun getCount(): Int = itemsList.size
            
            fun updateList(listItems: ArrayList<String>()){
                this.itemsList = listItems
                notifyDatSetChanged
            
            }
           
                }
               
            //Here I just explained two ways, we can do this many ways.
        

        【讨论】:

        • 添加到 ListView 的部分在哪里?
        • @OnieManiego 在这里我通过两种方式将项目添加到 listview,您可以在上面看到 1. listItems.add("a") listItems.add("b") listItems.add("c ") listItems.add("d") listItems.add("e") 这是我添加的第一种方式 2. for(items in array) listItems.add(items) 我从数组中添加所有项目的第二种方式
        • @OnieManiego 希望你能理解,如果对你有帮助,请点赞
        • @Federico Capece 如果您希望将列表项添加到列表视图中,您需要一个适配器类并将列表视图传递给适配器类。如果您想了解有关如何设置列表视图的更多详细信息,请参考 google 或 msg 我,我将分享代码
        • @Federico Capece 老实说我同意这一点,我会尽快更新我的答案,谢谢你的建议
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-01
        • 2016-01-01
        • 2011-10-05
        • 1970-01-01
        • 2013-03-22
        • 2014-08-03
        • 1970-01-01
        相关资源
        最近更新 更多