【Android|【Android ListView】解决使用onMeasure处理高度问题后复用问题
先来看个图:
文章图片
device-2017-11-29-103650.png 遇上这种需求在我还是小白的时候做法是这样的:
【【Android|【Android ListView】解决使用onMeasure处理高度问题后复用问题】emm,一切顺利 run。
惊喜的发现ListView显示的这是啥啊,后来才知道这是因为ListView跟ScrollView冲突的问题。
那么如何解决这个问题 方法1:在XML中写死
android:layout_width="match_parent"
android:layout_height="120dp"
方法2:自定义ListView在onMeasure里面计算高度
关键代码:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
第一种方法,显然适用性不高。
第二种方法,会让listview失去复用的机制,导致更新数据的时候卡顿。
那么问题来了,我怎么处理好呢?
其实ListView有这么一个方法
listView.addHeaderView(view);
把列表以上的控件,使用"View.inflate()",的方式,add到ListView上面,这样以来ListView就不会失去复用机制,上方的控件也能正常操作。需要注意的是,这样会使用上方的控件,其实就是ListView的item之一,下方列表在操作的时候,position需要 -1。
那么问题又来了,这么写的话,就需要把原本一个xml的方法拆成两个,上方控件也不能简单的findViewById。
为了解决这个问题,这里封装了一个ListHeadView,用来处理这个麻烦的操作。
此控件中已经处理了position的问题,代码如下,具体实现请看源码。
listHeadView.setOnItemClick(new ListHeadView.onItemClick() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {}
});
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
/**
* 描述:简单实现ListViewHeadView
*
* @author songdehuai
* @ClassName: com.songdehuai.headview.widget.ListHeadView
* @date 2017/11/10 9:22
*/
public class ListHeadView extends LinearLayout implements AdapterView.OnItemClickListener {private ListView mListView;
private BaseAdapter mAdapter;
public ListHeadView(Context context) throws Exception {
this(context, null, -1);
}public ListHeadView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, -1);
}public ListHeadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}void initViews(Context context) {
mListView = new ListView(context);
ViewGroup.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
mListView.setLayoutParams(layoutParams);
mListView.setOnItemClickListener(this);
}@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mAdapter != null) {
try {
View view = this.getChildAt(0);
if (mListView.getHeaderViewsCount() == 0) {
this.removeViewAt(0);
mListView.addHeaderView(view);
this.addView(mListView);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}public ListView listView() {
return mListView;
}public void setAdapter(BaseAdapter adapter) {
initViews(getContext());
this.mAdapter = adapter;
mListView.setAdapter(adapter);
}private onItemClick mOnItemClick;
public void setOnItemClick(onItemClick mOnItemClick) {
this.mOnItemClick = mOnItemClick;
}public interface onItemClick {
void onItemClick(AdapterView> parent, View view, int position, long id);
}@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
position = position - 1;
if (mOnItemClick != null) {
mOnItemClick.onItemClick(parent, view, position, id);
}
}
}
Github:https://github.com/songdehuai/HeadView
目前子View只能存在一个,就像ScrollView那样使用。
见识不多,能力不足,待优化的地方还很多。
推荐阅读
- 宽容谁
- 我要做大厨
- android第三方框架(五)ButterKnife
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘