วิธีเพิ่มองค์ประกอบเข้ากับ listView แบบไดนามิกใน Android


326

ใครสามารถอธิบายหรือแนะนำการสอนเพื่อสร้าง listView ใน android ได้หรือไม่?

นี่คือความต้องการของฉัน:

  • ฉันควรจะเพิ่มองค์ประกอบใหม่แบบไดนามิกโดยการกดปุ่ม
  • ควรเข้าใจได้ง่าย (อาจไม่มีการปรับปรุงประสิทธิภาพหรือการแปลงตัวอย่าง)

ฉันรู้ว่ามีคำถามไม่กี่ข้อในหัวข้อนี้โพสต์ที่นี่ใน StackOverflow แต่ไม่พบคำถามใด ๆ ที่จะตอบคำถามของฉัน ขอบคุณ!


3
คำตอบที่ได้รับคะแนนสูงสุดในขณะนี้จาก Shardul ถือว่ามีคุณภาพสูงและผู้ใช้ระบุว่าพวกเขารู้สึกว่าควรได้รับการยอมรับ คุณสามารถพิจารณารับได้หรือไม่?
Matt Welke

คำตอบ:


583

สร้างเค้าโครง XML ก่อนในres/layout/main.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มีประชาชนได้@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เป็นรายการที่เก็บข้อมูลที่แสดงใน ListView การแทรกและการถอดควรทำlistItemsทั้งหมด การเปลี่ยนแปลงในlistItemsควรจะสะท้อนให้เห็นในมุมมอง จัดการโดยArrayAdapter<String> adapterที่ควรได้รับการแจ้งเตือนเมื่อใช้:

adapter.notifyDataSetChanged();

อะแดปเตอร์อินสแตนซ์ที่มี 3 พารามิเตอร์: บริบทซึ่งอาจจะเป็นของคุณactivity/listactivity; เลย์เอาต์ของแต่ละรายการ และสุดท้ายคือรายการซึ่งเป็นข้อมูลจริงที่จะแสดงในรายการ


2
ฉันไม่เข้าใจว่า ListView แนบกับกิจกรรมของเราที่นี่ได้อย่างไร
Breedly

7
@Breedly เพราะมันเป็นListActivityและไม่ได้เป็นกิจกรรมที่มีรูปแบบที่มีมุมมองรายการ คุณไม่จำเป็นต้องค้นหามุมมอง ID ListActivity is an activity that includes a ListView as its only layout element by default. [...] (it) hosts a ListView objectขณะที่คุณสามารถอ่านบนอ้างอิง: ดังนั้นโดยปกติแล้วเมธอด (ตามที่setAdapterฯลฯ ) คือ "inside" Class
fllo

มาแสดงความสุขกันเถอะเมื่อคำตอบที่ถูกต้อง: /
support_ms

1
หากองค์ประกอบใน ArrayList มีความซับซ้อนมากขึ้นเช่นการโหลดจากอินเทอร์เน็ตและแต่ละรายการมีภาพวิดีโอและอะไรทำนองนั้นวิธีการนี้จะได้รับผลกระทบหรือไม่
zionpi

1
ฉันจะใช้สิ่งนี้เป็นชิ้นส่วนได้อย่างไร
Oamar Kanji

64

แทน

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

คุณสามารถโทรโดยตรง

adapter.add("New Item");

@gumuruh อะแดปเตอร์ตัวเองไม่แน่นอนดังนั้นเราจึงสามารถเพิ่มหรือลบวัตถุที่จะเรียกการแจ้งเตือน DatasetChanged () และ getView () ของ listView โดยอัตโนมัติ นี่เป็นการลดรหัสบรรทัดพิเศษ
venkat530

ดังนั้นโดยการเพิ่มอะแดปเตอร์โดยอัตโนมัติโทร informDatasetChanged ()? อ้อเข้าใจแล้ว. ขอบคุณ @ venkat530 แต่สิ่งที่เกี่ยวกับรายการตัวเอง ฉันหมายความว่าถ้าอย่างแรกเขาสร้าง arraylist ที่ใช้เป็นที่เก็บข้อมูลสำหรับอะแดปเตอร์ และตอนนี้คุณเพียงแค่เพิ่มไอเท็มลงในอะแดปเตอร์โดยตรงไปยังอาเรย์ลิสต์ ข้อมูลอาเรย์ลิสต์ได้รับการอัพเดท / ไม่ถูกแตะต้อง
gumuruh

1
@gumuruh ข้อที่สองคือแนวปฏิบัติที่ดีที่สุดเนื่องจากมีการซิงโครไนซ์
Ricardo

1
@gumuruh จากการทดลองคร่าวๆและซอร์สโค้ด ArrayAdapter [ github.com/android/platform_frameworks_base/blob/master/core/…ดูเหมือนว่าชุดข้อมูลพื้นฐานจะถูกแก้ไขด้วย
CCJ

ฉันได้คำตอบของ Shardul แล้วก็แตกออกและไม่สามารถหาวิธีซ่อมได้ ฉันคิดว่าฉันจะลองทำสิ่งนี้และ voila ก็ใช้ได้อีกครั้ง! ขอบคุณมาก! แม้ว่าฉันจะไม่ทราบว่าจะแก้ไขอย่างไรหรือทำไม ความคิดใด ๆ
donutguy640

55

ก่อนอื่นคุณต้องเพิ่ม ListView, EditText และปุ่มลงใน activity_main.xml ของคุณ

ตอนนี้ใน 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 ซึ่งมีเพียงปรมาจารย์ระดับสูงเท่านั้นที่รู้ ปัญหาเดียวของฉันในตอนนี้คือฉันจะเพิ่ม drawable และสิ่งต่าง ๆ ในมุมมองในรายการได้อย่างไร ดูเหมือนว่าฉันแค่เพิ่มสตริงเท่านั้น

การปรับให้เหมาะสมอาจเป็นการสร้างรายการวัตถุที่ไม่มีชื่อในอะแดปเตอร์มากกว่าการสร้างตัวชี้ 16 บิตไปยังวัตถุรายการ ซึ่งไม่ต้องการหลังจากสร้างอะแดปเตอร์เนื่องจากอะแดปเตอร์มีวิธีการเพิ่ม

17

หากคุณต้องการ ListView ใน AppCompatActivity แทนที่จะเป็น 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"

ดังนั้นตอนนี้คุณสามารถมีภายในปกติListViewAppCompatActivity


13

รหัสสำหรับไฟล์ 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 คุณจะผ่านการอ้างอิงไปยังข้อมูล ตอนนี้เมื่อใดก็ตามที่ข้อมูลนี้จะถูกเปลี่ยนแปลงมันจะส่งผลกระทบต่อมุมมองรายการและเพิ่มรายการเข้าไปหลังจากคุณจะเรียกใช้อะแดปเตอร์

หากคุณใช้ 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. สำหรับ (รายการในอาร์เรย์) listItems.add (รายการ) วิธีที่สองฉันเพิ่มรายการทั้งหมดจากอาร์เรย์
sirajudheen tk

@ OnieManiego ฉันหวังว่าคุณเข้าใจถ้าเป็นประโยชน์กับคุณกรุณา upvote
sirajudheen tk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.