Android benutzerdefiniertes Zeilenelement für ListView


75

Ich habe eine ListView, die das folgende Layout in ihren Zeilen haben sollte:

HEADER
Text

HEADERsollte statisch sein, aber die TextÄnderungen alle paar Sekunden.

Ich habe es implementiert, indem ich a ausgefüllt, an a String[] arrayübergeben ArrayAdapterund jedes Mal festgelegt habe, wenn sich die Daten ändern:

data_array = populateString();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1,  data_array);
listView.setAdapter(adapter);

Mein Problem ist, dass ich nicht weiß, wie ich die Daten im obigen Format anzeigen soll.

Danke im Voraus.



1
Erstellen Sie einen benutzerdefinierten Adapter und überschreiben Sie die Methode getView (), um Ihre Anforderungen zu erfüllen
Sankar V

1
Sie müssen Baseadapter mit XML-Layout für Zeilen in Ihrer
Listenansicht verwenden

1
Sie müssen ein benutzerdefiniertes Layout erstellen.
Amit

Antworten:


177

Fügen Sie diese row.xml Ihrem Layoutordner hinzu

<?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="match_parent"
    android:orientation="vertical" >
    
<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Header"/>

<TextView 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/text"/>
    
    
</LinearLayout>

Machen Sie Ihr XML-Hauptlayout so

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

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</LinearLayout>

Dies ist Ihr Adapter

class yourAdapter extends BaseAdapter {

    Context context;
    String[] data;
    private static LayoutInflater inflater = null;

    public yourAdapter(Context context, String[] data) {
        // TODO Auto-generated constructor stub
        this.context = context;
        this.data = data;
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return data.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return data[position];
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        View vi = convertView;
        if (vi == null)
            vi = inflater.inflate(R.layout.row, null);
        TextView text = (TextView) vi.findViewById(R.id.text);
        text.setText(data[position]);
        return vi;
    }
}

Ihre Java-Aktivität

public class StackActivity extends Activity {

    ListView listview;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listview = (ListView) findViewById(R.id.listview);
        listview.setAdapter(new yourAdapter(this, new String[] { "data1",
                "data2" }));
    }
}

die Ergebnisse

Geben Sie hier die Bildbeschreibung ein


2
Wenn Sie mit einem Fragment arbeiten, welches sollte das Argument anstelle des Kontexts sein, der das erste Argument für IhreAdapter-Konstruktormethode 'listview.setAdapter' ist (neuer yourAdapter (dies, neuer String [] {"data1", "data2"})); '
Saifee

Entschuldigung, aber ich bekomme null, wenn ich versuche, .setText zu verwenden. Hast du eine Vorstellung davon, was es sein kann?
LowFieldTheory

@ Novalink bedeutet, dass das TextView text = (TextView) vi.findViewById(R.id.text);null ist. Bist du sicher, dass das da R.id.textist?
William Kinaan

meine row.xml sieht genau so aus, nur gibt es einen text1 und einen text2.
LowFieldTheory

@ Novalink poste eine neue Frage und sende mir bitte den Link
William Kinaan

9

Verwenden Sie eine benutzerdefinierte Listenansicht.

Sie können auch das Aussehen der Zeile anpassen, indem Sie einen benutzerdefinierten Hintergrund verwenden. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical" 
 android:background="#0095FF"> //background color

<ListView android:id="@+id/list"
 android:layout_width="fill_parent"
 android:layout_height="0dip"
 android:focusableInTouchMode="false"
 android:listSelector="@android:color/transparent"
 android:layout_weight="2"
 android:headerDividersEnabled="false"
 android:footerDividersEnabled="false"
 android:dividerHeight="8dp" 
 android:divider="#000000" 
 android:cacheColorHint="#000000"
android:drawSelectorOnTop="false">
</ListView>  

Hauptaktivität

Definieren Sie populateString () in MainActivity

 public class MainActivity extends Activity {

   String data_array[];
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
            data_array = populateString(); 
    ListView ll = (ListView) findViewById(R.id.list);
    CustomAdapter cus = new CustomAdapter();
    ll.setAdapter(cus);
}

class CustomAdapter extends BaseAdapter
{
    LayoutInflater mInflater;


    public CustomAdapter()
    {
        mInflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return data_array.length;//listview item count. 
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position; 
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        final ViewHolder vh;
        vh= new ViewHolder();

        if(convertView==null )
         {
            convertView=mInflater.inflate(R.layout.row, parent,false);
                    //inflate custom layour
            vh.tv2= (TextView)convertView.findViewById(R.id.textView2);

         }
        else
        {
         convertView.setTag(vh);
        }
               //vh.tv2.setText("Position = "+position);
            vh.tv2.setText(data_array[position]);   
                           //set text of second textview based on position

        return convertView;
    }

 class ViewHolder
 {
    TextView tv1,tv2;
 }

   }  
}

row.xml. Benutzerdefiniertes Layout für jede Zeile.

<?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="match_parent"
 android:orientation="vertical" >

 <TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="Header" />

 <TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="TextView" />

 </LinearLayout>

Blasen Sie ein benutzerdefiniertes Layout auf. Verwenden Sie einen Ansichtshalter für reibungsloses Scrollen und Leistung.

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

http://www.youtube.com/watch?v=wDBM6wVEO70 . Der Vortrag handelt von der Listview-Leistung von Android-Entwicklern.

Geben Sie hier die Bildbeschreibung ein


OnCreate nach ll.SetAdapter (cus) Anwendung funktioniert plötzlich nicht mehr
Kalin Krastev

1
ist es ein Absturz?. Wenn ja, sollte das Absturzprotokoll Ihnen helfen, das Gleiche zu beheben
Raghunandan

Entschuldigung, es war meine Schuld. Ich verwende AndroidAnnotations und das Problem war, dass ich nicht das richtige R.layout verwendet habe. {Layout_id}. Ihr Code funktioniert gut.
Kalin Krastev

5

Erstellen Sie die Ressourcenlayoutdatei list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
<TextView
        android:id="@+id/header_text"
        android:layout_height="0dp"
        android:layout_width="fill_parent"
        android:layout_weight="1"
        android:text="Header"
        />
<TextView
        android:id="@+id/item_text"
        android:layout_height="0dp"
        android:layout_width="fill_parent"
        android:layout_weight="1"
        android:text="dynamic text"
        />
</LinearLayout>

und Adapter wie folgt initialisieren

adapter = new ArrayAdapter<String>(this, R.layout.list_item,R.id.item_text,data_array);

Dies ist die einfachste Methode, die ich gefunden habe, und sie hat beim ersten Versuch für mich funktioniert. Target Api Level 16.
Jahaziel

2

Schritt 1: Erstellen Sie eine XML-Datei

 <?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="match_parent"
        android:orientation="vertical">


        <ListView
            android:id="@+id/lvItems"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </LinearLayout>

Schritt 2: Studnet.java

package com.scancode.acutesoft.telephonymanagerapp;


public class Student
{
    String email,phone,address;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Schritt 3: MainActivity.java

 package com.scancode.acutesoft.telephonymanagerapp;

    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.ListView;

    import java.util.ArrayList;

    public class MainActivity extends Activity  {

        ListView lvItems;
        ArrayList<Student> studentArrayList ;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lvItems = (ListView) findViewById(R.id.lvItems);
            studentArrayList = new ArrayList<Student>();
            dataSaving();
            CustomAdapter adapter = new CustomAdapter(MainActivity.this,studentArrayList);
            lvItems.setAdapter(adapter);
        }

        private void dataSaving() {

            Student student = new Student();
            student.setEmail("abc@gmail.com");
            student.setPhone("1234567890");
            student.setAddress("Hyderabad");
            studentArrayList.add(student);


            student = new Student();
            student.setEmail("xyz@gmail.com");
            student.setPhone("1234567890");
            student.setAddress("Banglore");
            studentArrayList.add(student);

            student = new Student();
            student.setEmail("xyz@gmail.com");
            student.setPhone("1234567890");
            student.setAddress("Banglore");
            studentArrayList.add(student);

            student = new Student();
            student.setEmail("xyz@gmail.com");
            student.setPhone("1234567890");
            student.setAddress("Banglore");
            studentArrayList.add(student);
        }


    }

Schritt 4: CustomAdapter.java

  package com.scancode.acutesoft.telephonymanagerapp;

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

    import java.util.ArrayList;


    public class CustomAdapter extends BaseAdapter
    {
        ArrayList<Student> studentList;
        Context mContext;


        public CustomAdapter(Context context, ArrayList<Student> studentArrayList) {
            this.mContext = context;
            this.studentList = studentArrayList;

        }

        @Override
        public int getCount() {
            return studentList.size();
        }
        @Override
        public Object getItem(int position) {
            return position;
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            Student student = studentList.get(position);
            convertView = LayoutInflater.from(mContext).inflate(R.layout.student_row,null);

            TextView tvStudEmail = (TextView) convertView.findViewById(R.id.tvStudEmail);
            TextView tvStudPhone = (TextView) convertView.findViewById(R.id.tvStudPhone);
            TextView tvStudAddress = (TextView) convertView.findViewById(R.id.tvStudAddress);

            tvStudEmail.setText(student.getEmail());
            tvStudPhone.setText(student.getPhone());
            tvStudAddress.setText(student.getAddress());


            return convertView;
        }
    }

Ich erhalte die Meldung "Variable studentList wurde möglicherweise nicht initialisiert". Irgendwelche Ideen?
Foster

1

Sie können BaseAdapterIhrer Custome- XmlDatei folgen und sie erstellen , sie an sich binden BaseAdpterund mit der Listview hier aufgeführten Datei füllen , um die xmlDatei als Erforderlich zu ändern .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.