这些天遇到一个问题,就是我有个界面因为业务的需要,就必须做成listview嵌套listview,然后被嵌套的listview的Item里面有textview,刚开始也没什么,后来突然有条数据的字符串特别长,然后子listview的Item的textview就换行了,然后,然后你们懂得,子listview就显示异常了呀,内容就不能完全展示了。
其实google也是不推荐可以滚动的控件里面再次嵌套可以滚动的控件的。可是,无奈产品的需求呀。不过,已经有大神解决了这种嵌套问题,一般是有两种解决方法,一是重写listview的onMeasure方法,另外一种是设置完listview的adapter,动态测量listview的高度,当然这种情况是要求listview的子条目最外层布局是linearlayout线性布局了。其实说这个也是为这个textview换行问题做铺垫了。我嵌套listview时候用的是 第一种方法就是自定义了listview。但是依然出现了这个问题,好的,那咱们换换第二种方式呢?结果依然悲剧,依然是有问题。然后就去看看网上大牛都是怎么解决的。其实,看了下最主要的就是有两种解决方式,一种是用重写onMeasure的listview的方式,但是我试了不好使。另外一种就是重写textview的onMeasure,就是去除padding以及drawablePadding后,算出每行的宽度,然后用measureText方法测试赋值给textview的字符串在屏幕上占据的总长度,然后两者相除得到行数,然后在用textview每行的高度*行数得到textview应有的宽高,看起来也的确是合情合理呀。可是我试了还是不好使的。哎,日子可该怎么过呀。
既然试了都不好用。然后我就想用listview肯定是不行了。看来列表类的都不好用了。然后,然后我就用了linearlayout了。这也是万般无奈的做法,实属下下策。但是也的确是可以解决问题。算是一种临时性的解决方案吧。大家都知道线性布局,当它的orientation设置为vertical,然后它的子布局都一样,看起来会怎样?是不是也可以看做一个列表,虽然它不是。
接下来看具体实施,因为我之前用的就是listview嵌套listview,所以如上面所说我将子listview换成了一个orientation为vertical的linearlayout了。原来的listview的adapter其实是可以复用的。它就是用来构造添加进linearlayout里面的子view的。看如下代码:
private void addView(){
/**
* 下面的ExampleBean是实体Bean,同样listTemp是给adapter的list集合了(我写的假数据)
*/
List<ExampleBean> listTemp = new ArrayList<>();
ExampleAdapter exampleAdapter = new ExampleAdapter(listTemp,context);
//通过循环向linearlayout里面添加子view,相当于listview的Item了
for(int i=0;i<exampleAdapter.getCount();i++){
//通过adapter的getview方法获取子view
View view = exampleAdapter.getView(i, null, null);
//给子view设置margin属性(当然也可以有别的属性了)
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.setMargins(0, DevUtils.dp2px(10),0,0);
view.setLayoutParams(layoutParams);
//给linearlayout的Item设置点击事件,模拟listview的onItemClickListener
view.setOnClickListener(new MyOnClickListener(exampleAdapter.get(i),i));
linearlayout.addView(view);
}
}```
/**
* 要给linearlayout添加的点击事件监听
*/
private class MyOnClickListener implements View.OnClickListener{
private ExampleBean exampleBean;
private int currentPosition;
//通过构造方法将需要的参数传递进来(可根据自己业务需要扩展)
public MyOnClickListener(ExampleBean exampleBean,int position){
this.exampleBean = exampleBean;
this.position = position;
}
@Override
public void onClick(View v) {
//在这里写自己的业务跳转逻辑就好了
}
}```
是的,核心的代码就是如上的两个方法了。下面的MyOnClickListener就是给线性布局的每个Item添加的点击事件。这个也是我目前最可能遇到的业务场景了,就是Item的点击事件。如果是Item内部的事件,我们不需要做额外的处理了,交给adapter就好了。
以上就是这次遇到问题的解决过程。当然这个只是一个临时性的解决方法,因为listview这个列表控件的Item的复用性肯定比linearlayout好很多。如果大家有什么好的点子,欢迎分享,多多指教。如果不对之处,欢迎指出。周末愉快。