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自定义行项的主要内容,如果未能解决你的问题,请参考以下文章