Android listView单元格循环使用可变大小的单元格
我有一个列表视图。单元格的高度可变。这就导致了回收电池的问题——回收电池的高度可能不正确。关闭循环使用会使滚动变得太不稳定。如何在回收电池的同时获得正确的高度Android listView单元格循环使用可变大小的单元格,android,listview,Android,Listview,我有一个列表视图。单元格的高度可变。这就导致了回收电池的问题——回收电池的高度可能不正确。关闭循环使用会使滚动变得太不稳定。如何在回收电池的同时获得正确的高度 编辑:每个地方的高度都不同。没有可能值的简短列表。两个单元格类型 通常问题来自getView。我不确定您真正想要的是什么,因为您没有提供自定义适配器。但是,我给出了一个有两种不同单元格类型的示例,但是该单元格只包含一个textview 在这种情况下,所有的电池都会随着循环进行完全调整。仔细阅读并扩展/修改以满足您的需要 在您的Custom
编辑:每个地方的高度都不同。没有可能值的简短列表。两个单元格类型 通常问题来自getView。我不确定您真正想要的是什么,因为您没有提供自定义适配器。但是,我给出了一个有两种不同单元格类型的示例,但是该单元格只包含一个textview 在这种情况下,所有的电池都会随着循环进行完全调整。仔细阅读并扩展/修改以满足您的需要 在您的
CustomAdapter
private final class CustomArrayAdapter extends ArrayAdapter<String> {
//the fastest is to get the layout inflater once and not each time getView is called
private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public CustomArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
super(context, resource, textViewResourceId, objects);
}
...
//here depending on the item position determine if cell is of type 1 or 2
@Override
public int getItemViewType(int position) {
if (/* your type 1 criteria is match */) {
return TYPE_1;
} else {
return TYPE_2;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_1:
convertView = mInflater.inflate(R.layout.row_of_type_1, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.textview_type_1);
break;
case TYPE_2:
convertView = mInflater.inflate(R.layout.row_of_type_2, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.textview_type_2);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//get the text for that specific cell and set it
holder.text.setText(getMyCustomTextForThisCell());
return convertView;
}
}
static class ViewHolder {
TextView text;
}
private final class CustomArrayAdapter extends ArrayAdapter<String> {
//the fastest is to get the layout inflater once and not each time getView is called
private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public CustomArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
super(context, resource, textViewResourceId, objects);
}
...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.row_type, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.textview_in_your_row);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//get the text for that specific cell and set it
holder.text.setText(getMyCustomTextForThisCell());
return convertView;
}
}
static class ViewHolder {
TextView text;
}
单元布局 在示例中,我给出的文件row_type.xml(您所在行的布局文件)应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textview_in_your_row"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
不要忘记android:layout\u height=“wrap\u content”,否则单元格将无法调整大小
旁白 这篇旁白没有提到OP问题,但是如果人们因为标题中的细胞回收词而来到这里,他们可能会对以下事实感兴趣,即我在这里给出了一个完整的细胞回收示例,其中包含一个EditText
以下是我如何使用Xamarin解决这个问题的
public override View GetView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
int type = GetItemViewType(position);
if (convertView == null)
{
holder = new ViewHolder();
convertView = context.LayoutInflater.Inflate(Resource.Layout.my_row_layout, parent, false);
holder.myTextView = FindViewById<TextView>(Resource.Id.viewRow);
convertView.Tag = holder;
}
else
{
holder = (ViewHolder)convertView.Tag;
int heightWeWant = heights[type];
if (holder.myTextView.Height != heightWeWant) //height we have isn't what we want
{
AbsListView.LayoutParams parms = new AbsListView.LayoutParams(LinearLayout.LayoutParams.MatchParent, heightWeWant); //Width, Height //resize the view to the height we want
convertView.LayoutParameters = parms;
}
convertView.Tag = holder;
}
holder.myText = "Some text here";
return convertView;
}
public override View GetView(int位置、视图转换视图、视图组父视图){
视窗座;
int type=GetItemViewType(位置);
if(convertView==null)
{
holder=新的ViewHolder();
convertView=context.LayoutInflater.Inflate(Resource.Layout.my_row_Layout,parent,false);
holder.myTextView=FindViewById(Resource.Id.viewRow);
convertView.Tag=holder;
}
其他的
{
holder=(ViewHolder)convertView.Tag;
int heightWeWant=高度[类型];
如果(holder.myTextView.Height!=heightWeWant)//我们拥有的高度不是我们想要的
{
AbsListView.LayoutParams parms=新的AbsListView.LayoutParams(LinearLayout.LayoutParams.MatchParent,heightWeWant);//宽度,高度//将视图调整为所需高度
convertView.LayoutParameters=parms;
}
convertView.Tag=holder;
}
holder.myText=“此处有一些文本”;
返回视图;
}
每行的大小是否不同?甚至当你有不同的高度时,你知道你会有多少不同的高度吗?你使用getitemviewtype了吗?我认为你的问题没有解决办法(无限不同的类型+回收)。不管怎样,我把问题投了更高的票,让我们看看是否会有一些有趣的答案。我不明白为什么不需要引用每种类型就可以拥有大量的类型?这是一个真实的案例还是一个假设的案例?你能提供更多的细节吗?高度取决于单元格中文本的高度。如果OP没有添加:“各地的高度都不同。没有可能的值的简短列表。”我不明白这一点,那么你的方法就是正确的。他所说的“各地不同”是什么意思。我的意思是,我第一次遇到问题,因为我没有在正确的位置进行setTag,所以只能循环使用1种类型。我不能确定,但我怀疑他是说所有视图都可以有不同的类型。由于两个视图需要具有相同的类型才能在另一个视图中进行转换,如果它们都具有不同的类型,那么回收将一事无成——它们都是相同的类型,因为它们的内容是相同的类型。但是,根据文本的长度,高度可能相当高,也可能相当短。因此,如果我正确理解,您有一个带有textview的单元格,并且希望显示文本,但每个单元格都有不同长度的文本?如果是这样的话,我的代码就是这么做的。删除第二种类型,只使用一种,它就会工作。重用的目的是获取标签并将标签设置在正确的位置。