都在骂钉钉的同时,我却仿照他的群列表开始学习

都在骂钉钉的同时,我却仿照他的群列表开始学习

(代码过长,可以到http://blog.houxinlin.com/project/android/dingding.tar.gz进行下载)

一、效果图

二、实现过程

首先定义数据信息类,包括基本的姓名,头像,加入时间。家长和学生扩展自BaseInfo

学生信息定义如下,并扩展了一个家长集合。

家长信息定义如下,其中扩展了和学生的关系名称,并持有一份学生的信息。

MainActivity.java

这里的学生和家长信息使用Android提供的ArrayMap保存,key是单个字母,value是一堆StudentEntity集合,而StudentEntity中又包含一堆StudentFamily集合,存放多个家长信息。

首先是把所有学生的姓名拼音首字母提取出来,然后存放到ArrayMap中(ArrayMap可以通过下标进行访问元素)。最终形成单个字母对应多个学生,单个学生又对应多个家长信息的结构。

提取拼音可以使用com.belerweb:pinyin4这个框架。

implementation 'com.belerweb:pinyin4j:2.5.0'

import android.os.Bundle;

import android.util.ArrayMap;

import androidx.appcompat.app.AppCompatActivity;

import androidx.recyclerview.widget.LinearLayoutManager;

import androidx.recyclerview.widget.RecyclerView;

import com.hxl.gongzhonghaodemo.dingding.adapter.StudentAdapter;

import com.hxl.gongzhonghaodemo.dingding.entitys.StudentEntity;

import com.hxl.gongzhonghaodemo.dingding.entitys.StudentFamily;

import net.sourceforge.pinyin4j.PinyinHelper;

import java.time.LocalDateTime;

import java.util.ArrayList;

import java.util.List;

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();

private RecyclerView mRecyclerView;

private StudentAdapter mStudentAdapter;

private ArrayMap> mStudentMap;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

initData();

mStudentAdapter = new StudentAdapter(this, mStudentMap);

mRecyclerView.setAdapter(mStudentAdapter);

}

private void initData() {

mStudentMap = new ArrayMap<>();

List mStudentEntities = new ArrayList<>();

mStudentEntities.add(new StudentEntity.Builder()

.setName("鲁迅")

.setUrl("http://img5.imgtn.bdimg.com/it/u=3841760432,773912449&fm=11&gp=0.jpg")

.addFamily(new StudentFamily("鲁豫", "", LocalDateTime.now(), "陌生人"))

.addFamily(new StudentFamily("鲁智深", "", LocalDateTime.now(), "陌生人"))

.build());

mStudentEntities.add(new StudentEntity.Builder()

.setName("孔子")

.setUrl("http://img2.imgtn.bdimg.com/it/u=3927250071,3411280749&fm=26&gp=0.jpg")

.addFamily(new StudentFamily("孔融", "", LocalDateTime.now(), "儿子"))

.addFamily(new StudentFamily("老子", "", LocalDateTime.now(), "陌生人"))

.addFamily(new StudentFamily("孔明灯", "", LocalDateTime.now(), "天灯"))

.build());

mStudentEntities.add(new StudentEntity.Builder()

.setName("李白")

.setUrl("")

.addFamily(new StudentFamily("李太白", "http://img0.imgtn.bdimg.com/it/u=3293099503,606929711&fm=26&gp=0.jpg", LocalDateTime.now(), "爸爸"))

.addFamily(new StudentFamily("李太黑", "", LocalDateTime.now(), "妈妈"))

.build());

mStudentEntities.add(new StudentEntity.Builder()

.setName("杜甫")

.setUrl("http://img0.imgtn.bdimg.com/it/u=3593446461,3335288407&fm=26&gp=0.jpg")

.addFamily(new StudentFamily("杜太甫", "http://img0.imgtn.bdimg.com/it/u=3293099503,606929711&fm=26&gp=0.jpg", LocalDateTime.now(), "爷爷"))

.addFamily(new StudentFamily("杜绢花", "https://img.pconline.com.cn/images/upload/upc/tx/photoblog/1405/25/c1/34592098_34592098_1400979781687_mthumb.jpg", LocalDateTime.now(), "妈妈"))

.build());

mStudentEntities.add(new StudentEntity.Builder()

.setName("白居易")

.setUrl("http://img2.imgtn.bdimg.com/it/u=1473741299,1011020019&fm=26&gp=0.jpg")

.addFamily(new StudentFamily("白行简", "http://img0.imgtn.bdimg.com/it/u=3293099503,606929711&fm=26&gp=0.jpg", LocalDateTime.now(), "姑姑"))

.addFamily(new StudentFamily("白天鹅", "", LocalDateTime.now(), "宠物"))

.addFamily(new StudentFamily("杜甫", "", LocalDateTime.now(), "兄弟"))

.build());

for (int i = 0; i < mStudentEntities.size(); i++) {

StudentEntity item = mStudentEntities.get(i);

char sort = getPinYinFirstLetter(item.getName().charAt(0));

if (mStudentMap.get(sort) == null) {

List data = new ArrayList<>();

data.add(item);

mStudentMap.put(sort, data);

} else {

List studentEntities = mStudentMap.get(sort);

studentEntities.add(item);

}

}

}

private void initView() {

mRecyclerView = findViewById(R.id.recycleview);

mRecyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));

}

public char getPinYinFirstLetter(char str) {

String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(str);

if (pinyinArray==null){

return '#';

}

return pinyinArray==null?'#':Character.toUpperCase(pinyinArray[0].charAt(0));

}

}

StudentAdapter.java

RecyclerView的适配器,这里自定义了几个ViewGroup,如StudentViewGroup用来存放学生信息的视图列表。

import android.content.Context;

import android.util.ArrayMap;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

import androidx.annotation.NonNull;

import androidx.recyclerview.widget.RecyclerView;

import com.hxl.gongzhonghaodemo.R;

import com.hxl.gongzhonghaodemo.dingding.entitys.StudentEntity;

import com.hxl.gongzhonghaodemo.dingding.ui.StudentViewGroup;

import java.util.List;

public class StudentAdapter extends RecyclerView.Adapter {

private Context mContext;

private ArrayMap> map;

public StudentAdapter(Context context, ArrayMap> map) {

this.mContext = context;

this.map = map;

}

@NonNull

@Override

public RecycleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View inflate = LayoutInflater.from(mContext).inflate(R.layout.item_group, parent, false);

return new RecycleViewHolder(inflate);

}

@Override

public void onBindViewHolder(@NonNull RecycleViewHolder holder, int position) {

holder.mTvSort.setText(map.keyAt(position)+"");

List studentEntities = map.get(map.keyAt(position));

for (int i = 0; i

holder.mStudentList.addStudent(studentEntities.get(i));

}

}

@Override

public int getItemCount() {

return map==null?0:map.size();

}

public class RecycleViewHolder extends RecyclerView.ViewHolder{

TextView mTvSort;

StudentViewGroup mStudentList;

public RecycleViewHolder(@NonNull View itemView) {

super(itemView);

mTvSort=itemView.findViewById(R.id.tv_sort);

mStudentList =itemView.findViewById(R.id.student_list);

}

}

}

以下是学生信息的视图和家长信息的视图。

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.LinearLayout;

import android.widget.TextView;

import androidx.annotation.Nullable;

import com.hxl.gongzhonghaodemo.R;

import com.hxl.gongzhonghaodemo.dingding.entitys.BaseInfo;

import com.hxl.gongzhonghaodemo.dingding.entitys.StudentEntity;

import com.hxl.gongzhonghaodemo.dingding.entitys.StudentFamily;

import com.hxl.gongzhonghaodemo.dingding.utils.DisplayUtils;

public class BaseItemLayout extends LinearLayout {

public BaseItemLayout(Context context) {

super(context);

init();

}

public BaseItemLayout(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

init();

}

public BaseItemLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init() {

setOrientation(LinearLayout.VERTICAL);

}

private View addItem(BaseInfo baseInfo, int resId) {

if (baseInfo == null) {

return null;

}

View mView = LayoutInflater.from(getContext()).inflate(resId, this, false);

if (baseInfo instanceof StudentFamily){

((TextView) mView.findViewById(R.id.tv_name))

.setText(((StudentFamily) baseInfo).getStudentEntity().getName()+"的"+((StudentFamily) baseInfo).getRelation()+"("+baseInfo.getName()+")");

}else {

((TextView) mView.findViewById(R.id.tv_name)).setText(baseInfo.getName());

}

ProfilePicture mProfilePicture = mView.findViewById(R.id.im_profile_picture);

int size = DisplayUtils.dip2px(getContext(), 40);

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(size, size);

mProfilePicture.setLayoutParams(params);

mProfilePicture.setName(baseInfo);

this.addView(mView);

return mView;

}

public View addItem(BaseInfo baseInfo) {

if (this instanceof StudentViewGroup) {

return addItem(baseInfo, R.layout.item_student);

} else {

return addItem(baseInfo, R.layout.item_student_family);

}

}

}

public class StudentViewGroup extends BaseItemLayout {

private static String TAG="StudentViewGroup";

private static Paint mNamePaint;

public StudentViewGroup(Context context) {

super(context);

}

public StudentViewGroup(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}

public StudentViewGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

public void addStudent(StudentEntity studentEntity){

//添加自个

View mView = addItem(studentEntity);

//添加家人

FamilyViewGroup mFamilyList = mView.findViewById(R.id.family_list);

mFamilyList.addFamilyName(studentEntity.getStudentFamilies());

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

}

}

import android.content.Context;

import android.util.AttributeSet;

import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import com.hxl.gongzhonghaodemo.dingding.entitys.StudentFamily;

import java.util.List;

public class FamilyViewGroup extends BaseItemLayout {

public FamilyViewGroup(Context context) {

super(context);

}

public FamilyViewGroup(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}

public FamilyViewGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

public void addFamilyName(List studentFamilies) {

for (int i = 0; i < studentFamilies.size(); i++) {

addItem(studentFamilies.get(i));

}

}

}

其中自定义了个圆角视图RoundRelativeLayout和头像视图ProfilePicture。当没有头像url地址时,使用自己名字后两位,如果有,则使用Glide加载。

package com.hxl.gongzhonghaodemo.dingding.ui;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PorterDuff;

import android.graphics.PorterDuffXfermode;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.View;

import android.widget.RelativeLayout;

public class RoundRelativeLayout extends RelativeLayout {

private final RectF mRectF = new RectF();

private final Paint maskPaint = new Paint();

private final Paint zonePaint = new Paint();

private View mView;

private Context mContext;

public RoundRelativeLayout(Context context) {

super(context);

init();

}

public RoundRelativeLayout(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}

public RoundRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init() {

maskPaint.setAntiAlias(true);

maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

zonePaint.setColor(Color.WHITE);

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

super.onLayout(changed, left, top, right, bottom);

mRectF.set(0,0,getWidth(),getHeight());

}

@Override

public void draw(Canvas canvas) {

canvas.saveLayer(mRectF, zonePaint, Canvas.ALL_SAVE_FLAG);

canvas.drawRoundRect(mRectF, getWidth(), getWidth(), zonePaint);

canvas.saveLayer(mRectF, maskPaint, Canvas.ALL_SAVE_FLAG);

super.draw(canvas);

canvas.restore();

}

}

import android.content.Context;

import android.graphics.Color;

import android.util.AttributeSet;

import android.view.Gravity;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import com.bumptech.glide.Glide;

import com.hxl.gongzhonghaodemo.dingding.entitys.BaseInfo;

public class ProfilePicture extends RoundRelativeLayout {

public ProfilePicture(Context context, AttributeSet attrs) {

super(context, attrs);

}

public ProfilePicture(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

public ProfilePicture(Context context) {

super(context);

}

public void setName(BaseInfo baseInfo) {

if (baseInfo.getProfilePicture() == null || baseInfo.getProfilePicture().length() == 0) {

TextView mName = new TextView(getContext());

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,

LinearLayout.LayoutParams.MATCH_PARENT);

mName.setLayoutParams(params);

String name = baseInfo.getName().length() > 2 ?

baseInfo.getName().substring(baseInfo.getName().length() - 2) : baseInfo.getName();

mName.setText(name);

mName.setGravity(Gravity.CENTER);

this.addView(mName);

mName.setTextColor(Color.WHITE);

return;

}

ImageView imageView =new ImageView(getContext());

imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

Glide.with(imageView).load(baseInfo.getProfilePicture()).into(imageView);

this.addView(imageView);

}

}

相关新闻

新浪微博怎么发长微博(新浪微博如何发长微博)
365bet体育在线大陆

新浪微博怎么发长微博(新浪微博如何发长微博)

🕒 07-12 👽 7981
刚刚!阿斯利康收购珐博进中国,获得罗沙司他在中国的独家权利
骨科影像|跗骨窦解剖与14例跗骨窦区病变的MR表现
365速发彩票app下载旧版

骨科影像|跗骨窦解剖与14例跗骨窦区病变的MR表现

🕒 07-19 👽 2347
游戏dlc放哪里 游戏dlc的安装和使用方法
365bet体育在线大陆

游戏dlc放哪里 游戏dlc的安装和使用方法

🕒 07-11 👽 2949
有多少爱可以重来
365速发彩票app下载旧版

有多少爱可以重来

🕒 07-16 👽 8911
10个让你提升棋力妥妥的办法
365速发彩票app下载旧版

10个让你提升棋力妥妥的办法

🕒 07-12 👽 2842