前言:
今天要给大家带来QQ聊天列表的仿写效果,写得不好地方请见谅~
概述:
- 环境:Android Studio 3.42
- 语言:Java
- 特点:简单,易懂,效果爆炸
展示:
项目技术:
- ListView 可以纵向滑动列表,下面demo实现了继承ListView的新列表,代码如下
MyListView extends ListView
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
//设置适配器
setAdapter(new MyAdapter());
}
public class MyAdapter extends BaseAdapter{
/*列表的行数*/
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(int position) {
return null;
}
/*返回列表item的序号*/
@Override
public long getItemId(int position) {
return position;
}
/*列表显示的内容*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(getContext(),R.layout.layout_qq,null);
return v;
}
}
}
- BaseAdapter 适配器,用于设置列表行数和每一行的内容
public class MyAdapter extends BaseAdapter{
/*列表的行数*/
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(int position) {
return null;
}
/*返回列表item的序号*/
@Override
public long getItemId(int position) {
return position;
}
/*列表显示的内容*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(getContext(),R.layout.layout_qq,null);
return v;
}
}
这里我们通过继承ListView得到一个列表对象,并实现了设置适配器得到列表的行数和内容,就实现了一个可滑动的列表,最后在xml文件里引用一下就OK了,效果如下
activity_main.xml引用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.day_10.MyListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
下面讲解如何实现类似QQ聊天列表的效果
- 圆形头像实现
MyImageView
public class MyImageView extends AppCompatImageView {
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void draw(Canvas canvas) {
/*新建路径,形成一个圆*/
Path path = new Path();
/*对应参数分别是圆心坐标,半径,顺逆方向*/
path.addCircle(getPivotX()+getWidth()/2,getPivotY()+getHeight()/2,getWidth()/2, Path.Direction.CCW);
/*剪掉与圆无关的部分*/
canvas.clipPath(path);
super.draw(canvas);
}
}
效果
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.day_10.MyImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/icon"
android:layout_marginStart="20dp"
android:scaleType="fitXY"/>
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginStart="20dp"
android:background="@color/colorPrimaryDark"/>
</LinearLayout>
简要说明:圆形头像的实现其实就是通过Android绘制时去掉圆形以外的部分,类似剪刀剪纸,一般图片是长方形的,剪切呈圆形当然需要有一圆形路径path,还要有剪刀canvas的clipPath方法,然后返回的是和path一样路径形状的图片,所以通过继承AppCompatImageView(本身继承ImageView),重写draw方法,完成圆形图片的绘制,这里我随便选择了一张方形图片作为头像,实现效果如上
那么到这里我们实现了列表,左边头像,最后实现右边数据,当然为了模仿,聊天记录我们自己来写
- DataUtils 数据加载
public class DataUtils {
/**
* 文件数据加载
* */
public static Object loadDataInFile(){return null;}
/**
* 自己构造的数据加载
* */
public static ArrayList<FriendMode> loadDataInMine(){
ArrayList<FriendMode> modes = new ArrayList<>();
for(int i=0;i<10;i++)
{
FriendMode mode = new FriendMode(R.drawable.one,"Android开发");
modes.add(mode);
}
return modes;}
/**
* 数据库加载数据
* */
public static Object loadDataInRoom(){return null;}
/**
* 网络数据加载
* */
public static Object loadDataInSite(){return null;}
}
为了方便,这里每条信息都会是一样的
- DataManager 获取创建的数据
import java.util.ArrayList;
public class DataManager {
/**
* 数据资源
* */
private ArrayList<FriendMode> dataSource;
public ArrayList<FriendMode> getDataSource() {
return dataSource;
}
/**
* 单例对象
* */
private DataManager(){loadData();}
public static final DataManager shareManager = new DataManager();
/**
* 加载数据
* */
private void loadData(){dataSource = DataUtils.loadDataInMine();}
}
- FriendItem 提取内容
public class FriendItem {
private FriendMode mode;
public View rootView;
private Context context;
public FriendItem(Context context,FriendMode mode){
this.mode = mode;
this.context = context;
initView();
}
private void initView()
{
View v = View.inflate(context,R.layout.layout,null);
ImageView icon = v.findViewWithTag(context.getString(R.string.iconTag));
TextView name = v.findViewWithTag(context.getResources().getString(R.string.nameTag));
icon.setImageResource(mode.id);
name.setText(mode.name);
rootView = v;
}
}
- MyListView 显示内容
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
setAdapter();
}
private void setAdapter(){
setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return DataManager.shareManager.getDataSource().size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
FriendItem friendItem = new FriendItem(getContext(),DataManager.shareManager.getDataSource().get(i));
return friendItem.rootView;
}
}
}
简要说明:这里的FriendItem类实现了ImageView和TextView的提取以及对应内容的设置
总结:这个demo复用性很高,因为很多代码使用了许多类来封装,方便添加和设置,如果不想用也不会删除很多代码,只需在 xml里注释掉即可,虽然效果还有待提高,但是QQ聊天列表的功能实现了,感谢大家的阅读,有不足的地方还请留言