Android:包含不同项的listview的xml布局
我正在读这个教程。我想创建一个包含不同类型行的列表视图。我知道如何创建适配器,但是xml布局呢?所以我定义了一个xml布局,如下所示:Android:包含不同项的listview的xml布局,android,listview,layout,Android,Listview,Layout,我正在读这个教程。我想创建一个包含不同类型行的列表视图。我知道如何创建适配器,但是xml布局呢?所以我定义了一个xml布局,如下所示: <ListView/> <TextView android:id="@+id/id1" /> <TextView android:id="@+id/id2" /> <ImageView android:id="@+id/id3" /> <TextView android:id="@+id/id4" /
<ListView/>
<TextView android:id="@+id/id1" />
<TextView android:id="@+id/id2" />
<ImageView android:id="@+id/id3" />
<TextView android:id="@+id/id4" />
}
xml 1:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="left"
android:layout_margin="0dp">
<!-- android:background="#0094ff" -->
<ListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fastScrollEnabled="true"
android:scrollbarStyle="insideInset"
android:textFilterEnabled="false"
android:divider="@null"
android:layout_margin="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:paddingLeft="15dp"
android:paddingRight="22dp"/>
</LinearLayout>
xml2
这不会是个问题。但我认为你的教程错了 您需要为行定义布局 如果希望行能够包含文本或图像,则需要将这两个视图都添加到布局中 现在在适配器中,您可以在其中填写列表,并决定要设置的项目 假设有两个字符串和一个图像
因此,您为前两行设置了文本,并为第三行添加了图像。您不必为自己预定义每一行,因为我想这就是您要做的。您需要覆盖
getViewItemType
和getViewTypeCount
。您还需要自定义布局
getItemViewType(int-position)
-返回基于位置应使用的布局类型的信息
你应该看看链接中的视频
然后
这可能是一种错误的方法。如果ListView中只有一个组件,请使用简单适配器,否则请使用自定义适配器和单独的XML作为列表行 示例代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listhistory);
initcomponents();
ArrayList<HashMap<String, String>> alist = new ArrayList<HashMap<String, String>>();
for (int i = 1; i < 20; i++) {
HashMap<String, String> hmap = new HashMap<String, String>();
hmap.put("date", "" + i + "/13");
hmap.put("restaurant", "Restaurant" + i);
hmap.put("distance", "" + (i * 100) + "kms");
alist.add(hmap);
}
final CustomListAdapter adapter = new CustomListAdapter(this,
R.layout.listitemhistory, alist);
list.setAdapter(adapter);
}
private void initcomponents() {
list = (ListView) findViewById(R.id.history_lst_list);
}
public void backButtonClick(View v) {
finish();
}
class CustomListAdapter extends ArrayAdapter<HashMap<String, String>> {
Context context;
int textViewResourceId;
ArrayList<HashMap<String, String>> alist;
public CustomListAdapter(Context context, int textViewResourceId,
ArrayList<HashMap<String, String>> alist) {
super(context, textViewResourceId);
this.context = context;
this.alist = alist;
this.textViewResourceId = textViewResourceId;
}
public int getCount() {
return alist.size();
}
public View getView(int pos, View convertView, ViewGroup parent) {
Holder holder = null;
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
convertView = inflater.inflate(R.layout.listitemhistory,
parent, false);
holder = new Holder();
holder.date = (TextView) convertView
.findViewById(R.id.listitemhistory_txt_date);
holder.restaurant = (TextView) convertView
.findViewById(R.id.listitemhistory_txt_restaurant);
holder.distance = (TextView) convertView
.findViewById(R.id.listitemhistory_txt_distance);
holder.lin_background = (LinearLayout) convertView
.findViewById(R.id.history_lin_background);
convertView.setTag(holder);
holder = (Holder) convertView.getTag();
holder.date.setText(alist.get(pos).get("date"));
holder.restaurant.setText(alist.get(pos).get("restaurant"));
holder.distance.setText(alist.get(pos).get("distance"));
return convertView;
}
class Holder {
TextView date, restaurant, distance;
LinearLayout lin_background;
}
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.listhistory);
初始化组件();
ArrayList alist=新的ArrayList();
对于(int i=1;i<20;i++){
HashMap hmap=新的HashMap();
hmap.put(“日期”,“i+”/13”);
hmap.put(“餐厅”、“餐厅”+i);
hmap.put(“距离”、“i*100)+“公里”);
列表添加(hmap);
}
最终CustomListAdapter=新CustomListAdapter(此,
R.layout.listitemhistory,alist);
list.setAdapter(适配器);
}
私有组件(){
list=(ListView)findViewById(R.id.history\u lst\u list);
}
公共无效backButtonClick(视图v){
完成();
}
类CustomListAdapter扩展了ArrayAdapter{
语境;
int textViewResourceId;
阵列主义者;
公共CustomListAdapter(上下文,int textViewResourceId,
ArrayList(列表){
super(上下文,textViewResourceId);
this.context=上下文;
this.alist=alist;
this.textViewResourceId=textViewResourceId;
}
public int getCount(){
返回alist.size();
}
公共视图getView(int pos、视图转换视图、视图组父视图){
Holder=null;
充气机=((活动)上下文)
.getLayoutInflater();
convertView=充气机。充气(R.layout.listitemhistory,
父母,假);
保持架=新保持架();
holder.date=(TextView)convertView
.findViewById(R.id.listitemhistory\u txt\u日期);
holder.restaurant=(TextView)convertView
.findviewbyd(R.id.listitemhistory_txt_餐厅);
holder.distance=(TextView)convertView
.findViewById(R.id.listitemhistory\u txt\u距离);
holder.lin_background=(LinearLayout)convertView
.findviewbyd(R.id.历史\林\背景);
convertView.setTag(支架);
holder=(holder)convertView.getTag();
holder.date.setText(alist.get(pos.get)(“日期”);
holder.restaurant.setText(alist.get(pos.get)(“restaurant”);
holder.distance.setText(alist.get(pos.get(“距离”));
返回视图;
}
阶级持有者{
text查看日期、餐厅、距离;
线性布局林_背景;
}
}
- 我刚刚解决了为不同行创建不同布局的问题。
- 在相应的xml文件中定义所有不同的布局
- 重写getViewTypeCount()方法并从中返回定义的布局数
- 重写getItemViewType()方法,并根据listview中元素的“位置”与建议的xml布局之间的关系定义条件并返回适当的整数值
- 通过在getView()方法中调用getItemViewType()方法,我们可以得到布局对应的数字,然后使用相应的xml布局对convertView进行充气。然后通过使用findViewById(),您可以将值放入ViewHolder类和setText中定义的TextView类的对象中,或者您可以进一步执行的任何操作。 就这么简单。 假设我们有4种布局类型和4个xml文件,分别命名为element1、element2、element3、element4和两个常见的textview id text1、text2
@覆盖
public int getItemViewType(int位置){
如果(位置%4==0){
返回0;
}否则如果(位置%4==1){
返回1;
}否则如果(位置%4==2){
返回2;
}
返回3;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
switch (type) {
case 0: {
convertView = mInflater.inflate(R.layout.element1, null);
break;
}
case 1: {
convertView = mInflater.inflate(R.layout.element2, null);
break;
}
case 2: {
convertView = mInflater.inflate(R.layout.element3, null);
break;
}
case 3: {
convertView = mInflater.inflate(R.layout.element4, null);
break;
}
}
holder = new ViewHolder();
holder.txt1 = (TextView) convertView.findViewById(R.id.text1);
holder.txt2 = (TextView) convertView.findViewById(R.id.text2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String rowItem = null;
rowItem = rowItems[position];
holder.txt1.setText(rowItem);
rowItem = rowItems[position+1];
holder.txt1.setText(rowItem);
return convertView;
}
private class ViewHolder {
TextView txt1, txt2;
}
不同类型的行意味着什么?第一行具有不同的布局膨胀第二行listview中的行具有不同的布局膨胀?是的,您需要为所需的每种类型的行创建不同的布局。最简单、最健壮的方法。尝试使用一种类型的行,但出现空点异常!上面的代码:)@user1315621看起来您的textview未初始化。检查一下again@user1315621检查是否正在扩展包含textview的布局。如果您在提到您的textview初始化的行中获得NPE
<?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"
android:gravity="left"
android:layout_margin="0dp">
<TextView
android:id="@+id/listview1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="7dp"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:textSize="18sp"
android:textColor="#000000"
android:lines="1">
</TextView>
</LinearLayout>
private static final int TYPE_ITEM1 = 0;
private static final int TYPE_ITEM2 = 1;
private static final int TYPE_ITEM3 = 2;
int type;
@Override
public int getItemViewType(int position) {
if (position== 0){
type = TYPE_ITEM1;
} else if (position == 1){
type = TYPE_ITEM2;
}
else
{
type= TYPE_ITEM3 ;
}
return type;
}
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutInflater inflater = null;
int type = getItemViewType(position);
// instead of if else you can use a case
if (row == null) {
if (type == FIRST_TYPE) {
//infalte layout of type1
}
if (type == SECOND_TYPE) {
//infalte layout of type2
} else {
//infalte layout of normaltype
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listhistory);
initcomponents();
ArrayList<HashMap<String, String>> alist = new ArrayList<HashMap<String, String>>();
for (int i = 1; i < 20; i++) {
HashMap<String, String> hmap = new HashMap<String, String>();
hmap.put("date", "" + i + "/13");
hmap.put("restaurant", "Restaurant" + i);
hmap.put("distance", "" + (i * 100) + "kms");
alist.add(hmap);
}
final CustomListAdapter adapter = new CustomListAdapter(this,
R.layout.listitemhistory, alist);
list.setAdapter(adapter);
}
private void initcomponents() {
list = (ListView) findViewById(R.id.history_lst_list);
}
public void backButtonClick(View v) {
finish();
}
class CustomListAdapter extends ArrayAdapter<HashMap<String, String>> {
Context context;
int textViewResourceId;
ArrayList<HashMap<String, String>> alist;
public CustomListAdapter(Context context, int textViewResourceId,
ArrayList<HashMap<String, String>> alist) {
super(context, textViewResourceId);
this.context = context;
this.alist = alist;
this.textViewResourceId = textViewResourceId;
}
public int getCount() {
return alist.size();
}
public View getView(int pos, View convertView, ViewGroup parent) {
Holder holder = null;
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
convertView = inflater.inflate(R.layout.listitemhistory,
parent, false);
holder = new Holder();
holder.date = (TextView) convertView
.findViewById(R.id.listitemhistory_txt_date);
holder.restaurant = (TextView) convertView
.findViewById(R.id.listitemhistory_txt_restaurant);
holder.distance = (TextView) convertView
.findViewById(R.id.listitemhistory_txt_distance);
holder.lin_background = (LinearLayout) convertView
.findViewById(R.id.history_lin_background);
convertView.setTag(holder);
holder = (Holder) convertView.getTag();
holder.date.setText(alist.get(pos).get("date"));
holder.restaurant.setText(alist.get(pos).get("restaurant"));
holder.distance.setText(alist.get(pos).get("distance"));
return convertView;
}
class Holder {
TextView date, restaurant, distance;
LinearLayout lin_background;
}
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
switch (type) {
case 0: {
convertView = mInflater.inflate(R.layout.element1, null);
break;
}
case 1: {
convertView = mInflater.inflate(R.layout.element2, null);
break;
}
case 2: {
convertView = mInflater.inflate(R.layout.element3, null);
break;
}
case 3: {
convertView = mInflater.inflate(R.layout.element4, null);
break;
}
}
holder = new ViewHolder();
holder.txt1 = (TextView) convertView.findViewById(R.id.text1);
holder.txt2 = (TextView) convertView.findViewById(R.id.text2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String rowItem = null;
rowItem = rowItems[position];
holder.txt1.setText(rowItem);
rowItem = rowItems[position+1];
holder.txt1.setText(rowItem);
return convertView;
}
private class ViewHolder {
TextView txt1, txt2;
}