要实现上图的界面,直接想到是ListView添加Header。但在Flutter中,ListView 组件相当于RecyclerView,所以添加Header也用RecyclerView的原理:
封装ListPage组件,list_page.dart
使用及测试:异步加载网络数据使用
RecyclerView是Google推出的一款用来显示大量数据的android控件, 是ListView,GridView等控件的优化版。它的使用非常灵活,高度的解耦,强制使用ViewHolder,性能更优。
它取消了ListView的addHeaderView方法,所以不能像ListView那样方便的添加头部样式。
先上图说说我想实现的效果
其实就是在聊天的界面上方加入一个头部布局。头部布局里会显示聊天对象的信息。
我一开始的时候用的是 RecyclerViewHeader 这个github上的开源插件。 但是用在我的项目中有一个致命的问题 - 用户进入聊天的时候会先显示最新消息,这个时候是不需要加入头部样式的,而只用在用户手动上滑到最早信息的时候显示。但是,这个插件总是会在用户进入的时候显示头部样式,并且遮盖一部分的历史信息。
后来只能老老实实的巧用RecyclerView的Adapter,先判断是不是已经获取到了最早的信息,如果是的话,在position为0的时候,返回头部布局的view并添加头部数据。参考了 这篇文章 完成。
这个文章对RecyclerView如何加Header讲的很细致全面,不过它并没有动态添加数据到头部文件里,而我的聊天界面的头部布局需要动态添加聊天对象信息。于是我对作者的方法进行了一些修改。
如果是头部布局的话,作者的ListHolder直接返回空,因为他不需要为头部布局绑定任何数据,我会在ListHolder中获取头部布局中需要绑数据的控件,并重新onBind()方法,判断如果view是头部文件并且position为0的话,就动态添加数据。我的数据是通过重写Adapter的构造方法传过去的。
第一个头布局我 设置了一下 位置,目的是为了证明,在自定义下拉刷新时,当listview已经添加了一个headerview时候,可以继续添加一个headerview,不影响下拉刷新代码如下:
MainActivity
package com.ss.hsx
import android.app.Activity
import android.os.Bundle
import android.widget.ArrayAdapter
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
MyListView listView = (MyListView) findViewById(R.id.listView)
String[] data = new String[] { "第一个", "第二个", "第三个" }
ArrayAdapter<String>adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data)
listView.setAdapter(adapter)
}
}
MyListView
package com.ss.hsx
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ListView
public class MyListView extends ListView {
View one
public MyListView(Context context) {
super(context)
initHeaderView(context)
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs)
initHeaderView(context)
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle)
initHeaderView(context)
}
private void initHeaderView(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
one = inflater.inflate(R.layout.one, null)
View two = inflater.inflate(R.layout.two, null)
addHeaderView(one)
addHeaderView(two)
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//控制第一个头部布局的位置
one.setPadding(0, -1 * one.getHeight()/2, 0, 0)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)