前言:
今天要給大家?guī)鞶Q聊天列表的仿寫效果,寫得不好地方請見諒~
概述:
- 環(huán)境:Android Studio 3.42
- 語言:Java
- 特點(diǎn):簡單毅弧,易懂蔫仙,效果爆炸
展示:
項(xiàng)目技術(shù):
- ListView 可以縱向滑動列表鲸伴,下面demo實(shí)現(xiàn)了繼承ListView的新列表,代碼如下
MyListView extends ListView
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
//設(shè)置適配器
setAdapter(new MyAdapter());
}
public class MyAdapter extends BaseAdapter{
/*列表的行數(shù)*/
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(int position) {
return null;
}
/*返回列表item的序號*/
@Override
public long getItemId(int position) {
return position;
}
/*列表顯示的內(nèi)容*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(getContext(),R.layout.layout_qq,null);
return v;
}
}
}
- BaseAdapter 適配器灾票,用于設(shè)置列表行數(shù)和每一行的內(nèi)容
public class MyAdapter extends BaseAdapter{
/*列表的行數(shù)*/
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(int position) {
return null;
}
/*返回列表item的序號*/
@Override
public long getItemId(int position) {
return position;
}
/*列表顯示的內(nèi)容*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(getContext(),R.layout.layout_qq,null);
return v;
}
}
這里我們通過繼承ListView得到一個列表對象峡谊,并實(shí)現(xiàn)了設(shè)置適配器得到列表的行數(shù)和內(nèi)容,就實(shí)現(xiàn)了一個可滑動的列表刊苍,最后在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>
下面講解如何實(shí)現(xiàn)類似QQ聊天列表的效果
- 圓形頭像實(shí)現(xiàn)
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();
/*對應(yīng)參數(shù)分別是圓心坐標(biāo)正什,半徑啥纸,順逆方向*/
path.addCircle(getPivotX()+getWidth()/2,getPivotY()+getHeight()/2,getWidth()/2, Path.Direction.CCW);
/*剪掉與圓無關(guān)的部分*/
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>
簡要說明:圓形頭像的實(shí)現(xiàn)其實(shí)就是通過Android繪制時(shí)去掉圓形以外的部分,類似剪刀剪紙婴氮,一般圖片是長方形的斯棒,剪切呈圓形當(dāng)然需要有一圓形路徑path,還要有剪刀canvas的clipPath方法,然后返回的是和path一樣路徑形狀的圖片主经,所以通過繼承AppCompatImageView(本身繼承ImageView),重寫draw方法荣暮,完成圓形圖片的繪制,這里我隨便選擇了一張方形圖片作為頭像罩驻,實(shí)現(xiàn)效果如上
那么到這里我們實(shí)現(xiàn)了列表穗酥,左邊頭像,最后實(shí)現(xiàn)右邊數(shù)據(jù),當(dāng)然為了模仿砾跃,聊天記錄我們自己來寫
- DataUtils 數(shù)據(jù)加載
public class DataUtils {
/**
* 文件數(shù)據(jù)加載
* */
public static Object loadDataInFile(){return null;}
/**
* 自己構(gòu)造的數(shù)據(jù)加載
* */
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開發(fā)");
modes.add(mode);
}
return modes;}
/**
* 數(shù)據(jù)庫加載數(shù)據(jù)
* */
public static Object loadDataInRoom(){return null;}
/**
* 網(wǎng)絡(luò)數(shù)據(jù)加載
* */
public static Object loadDataInSite(){return null;}
}
為了方便骏啰,這里每條信息都會是一樣的
- DataManager 獲取創(chuàng)建的數(shù)據(jù)
import java.util.ArrayList;
public class DataManager {
/**
* 數(shù)據(jù)資源
* */
private ArrayList<FriendMode> dataSource;
public ArrayList<FriendMode> getDataSource() {
return dataSource;
}
/**
* 單例對象
* */
private DataManager(){loadData();}
public static final DataManager shareManager = new DataManager();
/**
* 加載數(shù)據(jù)
* */
private void loadData(){dataSource = DataUtils.loadDataInMine();}
}
- FriendItem 提取內(nèi)容
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 顯示內(nèi)容
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類實(shí)現(xiàn)了ImageView和TextView的提取以及對應(yīng)內(nèi)容的設(shè)置
總結(jié):這個demo復(fù)用性很高,因?yàn)楹芏啻a使用了許多類來封裝抽高,方便添加和設(shè)置判耕,如果不想用也不會刪除很多代碼,只需在 xml里注釋掉即可厨内,雖然效果還有待提高祈秕,但是QQ聊天列表的功能實(shí)現(xiàn)了渺贤,感謝大家的閱讀雏胃,有不足的地方還請留言