ListView的Android自定义行项

Posted

技术标签:

【中文标题】ListView的Android自定义行项【英文标题】:Android custom Row Item for ListView 【发布时间】:2013-03-27 18:35:16 【问题描述】:

我有一个 ListView,它的行中应该有以下布局:

HEADER
Text

HEADER 应该是静态的,但 Text 每隔几秒就会改变一次。

我通过填充String[] array 来实现它,将它传递给ArrayAdapter 并在每次数据更改时设置它:

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

我的问题是我不知道如何以上面的格式显示数据。

提前致谢。

【问题讨论】:

检查***.com/questions/13590627/android-listview-headers 创建自定义适配器并覆盖 getView() 方法以满足您的需要 您必须在列表视图中使用带有 xml 布局的 baseadapter 你必须创建一个自定义布局。 【参考方案1】:

将此 row.xml 添加到您的布局文件夹中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical" >
    
<TextView android:layout_
    android:layout_
    android:text="Header"/>

<TextView 
    android:layout_
    android:layout_
    android:id="@+id/text"/>
    
    
</LinearLayout>

让你的主要 xml 布局像这样

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

    <ListView
        android:id="@+id/listview"
        android:layout_
        android:layout_ >
    </ListView>

</LinearLayout>

这是你的适配器

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;
    

你的 java 活动

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" ));
    

结果

【讨论】:

使用片段时,应该用什么代替上下文的参数,这是 yourAdapter 构造方法的第一个参数 'listview.setAdapter(new yourAdapter(this, new String[] "data1", "数据2" ));' 抱歉,迟到了,但是当我尝试使用 .setText 时,我得到了 null。你知道它是什么吗? @Novalink 表示TextView text = (TextView) vi.findViewById(R.id.text); 为空,您确定R.id.text 存在吗? 我的row.xml看起来一模一样,只是有一个text1和text2。 @Novalink 发布一个新问题并将链接发送给我【参考方案2】:

使用自定义列表视图。

您还可以通过自定义背景来自定义行的外观。 activity_main.xml

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

<ListView android:id="@+id/list"
 android:layout_
 android:layout_
 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>  

主活动

在 MainActivity 中定义 populateString()

 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;
 

     

行.xml。每行的自定义布局。

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

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

 <TextView
    android:id="@+id/textView2"
    android:layout_
    android:layout_
    android:layout_gravity="center"
    android:text="TextView" />

 </LinearLayout>

膨胀自定义布局。使用视图支架以实现平滑滚动和性能。

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

http://www.youtube.com/watch?v=wDBM6wVEO70。演讲是关于 android 开发者的 listview 性能。

【讨论】:

在 ll.SetAdapter(cus) 应用程序突然停止工作后的 OnCreate 是崩溃了吗?如果是这样,崩溃日志应该可以帮助您修复相同的问题 对不起,这是我的错。我正在使用 AndroidAnnotations,问题是我没有使用正确的 R.layout.layout_id。您的代码运行良好。【参考方案3】:

创建资源布局文件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_
          android:layout_>
<TextView
        android:id="@+id/header_text"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:text="Header"
        />
<TextView
        android:id="@+id/item_text"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:text="dynamic text"
        />
</LinearLayout>

并像这样初始化适配器

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

【讨论】:

这是我发现的最简单的方法,第一次尝试对我有用。目标 API 级别 16。【参考方案4】:

第 1 步:创建 XML 文件

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


        <ListView
            android:id="@+id/lvItems"
            android:layout_
            android:layout_
            />
    </LinearLayout>

第 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;
    

第 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);
        


    

第四步: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;
        
    

【讨论】:

我得到“变量 studentList 可能没有被初始化”。有什么想法吗?【参考方案5】:

您可以关注BaseAdapter 并创建您的客户Xml 文件并将其与您绑定BaseAdpter 并使用Listview 填充它see here 需要将xml 文件更改为Require。

【讨论】:

以上是关于ListView的Android自定义行项的主要内容,如果未能解决你的问题,请参考以下文章

每行具有不同布局的Android ListView

如何构建包含 ListView.Builder 的自定义行,以在颤动中构建 ElevatedButton?

ListView 从 EditText 更新

在 Android Studio 中向列表视图添加自定义行

在片段android中创建listview

如何突出显示 ListView-Items