如何在Android中动态添加元素到listView


326

谁能解释或建议一个在Android中创建listView的教程?

这是我的要求:

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

我知道有关此主题的问题很多,在此处发布在StackOverflow上,但是找不到任何可以回答我问题的问题。谢谢!


3
Shardul当前投票最高的答案被认为是高质量的,用户表示他们应该接受它。您可以考虑接受吗?
马特·韦尔克

Answers:


583

首先在项目的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>

这是一个简单的布局,顶部有一个按钮,底部有一个列表视图。请注意,的ListViewID @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<String> adapter,应使用以下方法通知:

adapter.notifyDataSetChanged();

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


2
我不明白ListView如何将自己附加到此处的活动中。
2013年

7
@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等)位于类的“内部”。
2014年

让我们在获得正确答案时表现出幸福:/
support_ms 2014年

1
如果ArrayList中的元素更复杂(例如从Internet加载)并且每个项目都包含图像视频之类的东西,这种方法是否会影响性能?
zionpi '16

1
我该如何在一个片段中实现呢?
奥马尔·汉吉(Oamar Kanji)

64

代替

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

你可以直接打电话

adapter.add("New Item");

@gumuruh适配器本身是可变的,因此我们可以直接添加或删除将自动调用listView的notifyDatasetChanged()和getView()的对象。这减少了多余的代码行。
venkat530 2014年

所以通过添加到适配器中自动调用notifyDatasetChanged()?哦,我明白了。谢谢@ venkat530。但是列表本身呢?我的意思是,如果首先说他创建了一个arraylist用作适配器的数据容器。现在,您只需将一个项目直接添加到适配器即可,而不是添加到arraylist。数组列表数据会被更新/保持不变吗?
gumuruh 2014年

1
@gumuruh第二个是最佳实践,因为它是同步的。
里卡多

1
来自粗略实验的@gumuruh和ArrayAdapter源代码[ github.com/android/platform_frameworks_base/blob/master/core/…],看起来基础数据集也将被修改。
CCJ

我让Shardul的答案起作用了,然后中断了它,却不知道如何修复它。一时兴起,我想我会尝试一下,瞧,它又能正常工作了!非常感谢你!虽然,我不知道如何或为什么要修复它。任何的想法?
donutguy640

55

首先,您必须在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();
        }
    });
}

这对我有用,希望对您有所帮助


4
非常好的解释,尤其感谢您对适配器项的解释-似乎神奇地出现在其他所有人的示例中。:)
raddevus

1
这是我为此找到的最好的例子:)
Dinuka Salwathura,

这个答案满足了人们的要求。简单干净,没有复杂的改进。最重要的答案实际上是ListActivity,只有高级大师才知道。我现在唯一的问题是如何在列表中的视图中添加可绘制对象和东西。在我看来,我只是添加字符串。

一种优化可能是在适配器中创建未命名的列表对象,而不是创建指向列表对象的16位指针。创建适配器后不需要,因为适配器具有add方法。

17

如果要在AppCompatActivity中使用ListView而不是ListActivity,则可以执行以下操作(修改@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"

所以现在您可以拥有ListView一个法线了AppCompatActivity


12

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>

屏幕截图

在此处输入图片说明


0

简短的答案:创建ListView时,将其传递给数据引用。现在,只要更改此数据,它将影响列表视图,并在您调用adapter.notifyDataSetChanged();之后向其中添加项目。

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


0

这是简单的答案如何在ListView Android Kotlin中动态添加数据

class MainActivity : AppCompatActivity(){

    var listItems = arrayListOf<String>()
    val array = arrayOf("a","b","c","d","e")
    var listView: ListView? = null

    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)
        Log.e("TAG","listItems array: $listItems")

    }
}

在这里,我仅说明了两种方式,我们可以通过多种方式来实现。


您将其添加到ListView的部分在哪里?
Onie Maniego

@OnieManiego在这里,我以两种方式将项目添加到listview,您可以在上面看到1.在listItems.add(“ a”)listItems.add(“ b”)listItems.add(“ c”)listItems.add(“ d “)listItems.add(” e“)这是我添加的第一种方法2. for(数组中的项目)listItems.add(items)第二种方法是我添加了数组中的所有项目
sirajudheen tk

@OnieManiego我希望您能理解,如果对您有帮助,请
投票
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.