类微信界面设计 v2.0
前言
在微信 v1.0版本上加上RecyclerView,使微信的每一个界面切换时,中间可以显示内容,并且显示的内容可以动态变换:消息界面左滑,可以快捷删除消息;好友界面点击好友名字,会出现好友的联系方式;通讯录界面显示联系人和其电话号码,可以横向滑动(纵向滑动方法同理)。
一、实现效果
二、实现代码
1.相应的class文件
由于只有每个界面切换的内容改变,不用改变整体界面,因此不用更改MainActivity的内容,只需在原 v1.0的基础上,对每一个页面对应的Fragment增加相应的功能即可
如:newsFragment.class:
package com.example.wechat;
import android.app.Fragment;
import android.os.Bundle;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {@link Fragment} subclass.
*/
public class newsFragment extends Fragment {
private RecyclerView recyclerView;
private List<String> myList = new ArrayList<>();
private Context context;
private newsApapter adapter;
public newsFragment() {
// Required empty public constructor
}
private void initData(){
myList.add("蒲公英的约定");
myList.add("告白气球");
myList.add("Mojito");
myList.add("彩虹");
myList.add("稻香");
myList.add("青花瓷");
myList.add("说好不哭");
myList.add("烟花易冷");
myList.add("最长的电影");
myList.add("一路向北");
myList.add("晴天");
myList.add("以父之名");
myList.add("星晴");
myList.add("听妈妈的话");
myList.add("说好的幸福呢");
myList.add("龙卷风");
myList.add("发如雪");
}
private void initView1(){
context=this.getActivity();
adapter=new newsApapter(context,myList);
ItemTouchHelper.Callback callback = new SwipeItemTouchHelper(adapter);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerView);
LinearLayoutManager manager=new LinearLayoutManager(context);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.tab01, container, false);
recyclerView=view.findViewById(R.id.recyclerview1);
initData();
initView1();
return view;
}
}
同时,创建消息界面的XML文件rcv1_item.xml,做输出的界面,并建立与newsFragment.class对应的newsApapter.class,在界面中输出相应的内容,并控制界面的动态操作
如:rcv1_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:tools="http://schemas.android.com/tools"
android:layout_margin="8dp"
android:gravity="center"
android:background="@drawable/common_bg"
android:orientation="vertical">
<TextView
android:id="@+id/team_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerVertical="true"
android:textSize="20sp"
android:layout_marginLeft="8dp"
tools:text="内容" />
</LinearLayout>
newsApapter.class:
package com.example.wechat;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class newsApapter extends RecyclerView .Adapter<newsApapter.SwipeViewHolder> implements ItemTouchHelperListener{
private List<String>list;
private Context context;
private View inflater;
public newsApapter(Context context, List<String> list) {
this.context=context;
this.list=list;
}
@Override
public newsApapter.SwipeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater= LayoutInflater.from(context).inflate(R.layout.rcv1_item,parent,false);
SwipeViewHolder swipeviewholder=new SwipeViewHolder(inflater);
return swipeviewholder;
}
@Override
public void onBindViewHolder(newsApapter.SwipeViewHolder holder, int position) {
holder.teamContent.setText(list.get(position));
}
@Override
public int getItemCount() {return list.size();}
@Override
public void onItemDismiss(int position) {
if (position < 0 || position > getItemCount()) {
return;
}
list.remove(position);
notifyItemRemoved(position);
if (position != list.size()) {
notifyItemRangeChanged(position, list.size() - position);
}
}
public class SwipeViewHolder extends RecyclerView.ViewHolder{
TextView teamContent;
public SwipeViewHolder(View itemView) {
super(itemView);
teamContent = itemView.findViewById(R.id.team_content);
}
}
}
同时,建立控制滑动操作的class文件,实现在消息界面左滑删除消息的功能
如:SwipeItemTouchHelper.class:
package com.example.wechat;
import android.graphics.Canvas;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
public class SwipeItemTouchHelper extends ItemTouchHelper.Callback{
private newsApapter myAdapter;
public SwipeItemTouchHelper(newsApapter adapter) {
myAdapter = adapter;
}
/**
* 设置滑动类型标记
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = 0; // 禁止上下拖动
int swipeFlags = ItemTouchHelper.LEFT; // 只允许从右向左滑动
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
/**
* 滑动删除 Item 的操作
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
myAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
/**
* 设置 Item 不支持长按拖动
*/
@Override
public boolean isLongPressDragEnabled() {
return false;
}
/**
* 设置 Item 支持滑动
*/
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
/**
* Item 被选中时候,改变 Item 的背景
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// item 被选中的操作
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundResource(R.drawable.select_bg);
}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 移动过程中重新绘制 Item,随着滑动的距离,设置 Item 的透明度
*/
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
float x = Math.abs(dX) + 0.5f;
float width = viewHolder.itemView.getWidth();
float alpha = 1f - x / width;
viewHolder.itemView.setAlpha(alpha);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
/**
* 用户操作完毕或者动画完毕后调用,恢复 item 的背景和透明度
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 操作完毕后恢复颜色
viewHolder.itemView.setBackgroundResource(R.drawable.common_bg);
viewHolder.itemView.setAlpha(1.0f);
super.clearView(recyclerView, viewHolder);
}
}
2.相应的xml文件
在控制消息界面的tab01.xml文件中,添加RecyclerView,用于列表形式输出
如:tab01.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:overScrollMode="never"
android:scrollbars="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
同时可以自由改变背景,在drawable下建立common_bg.xml控制一般情况下界面背景颜色,同时建立select_bg.xml实现操作后的颜色改变
如:common_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="#87CEFA" />
<stroke android:width="4dp" android:color="@android:color/darker_gray" />
</shape>
</item>
</selector>
select_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="#00BFFF" />
<stroke android:width="4dp" android:color="#87CEFA" />
</shape>
</item>
</selector>
总结
在这次的作业中,我学会了怎么在不同的界面中通过RecyclerView实现不同的功能,并且将这些不同的功能集于一身,同时也对RecyclerView的功能和用法有了一定得了解。
参考网址:https://www.jianshu.com/p/c4cfe38a91ed
完整的代码已上传代码仓库:
https://gitee.com/wyy-52/my-wechat-v2.0/tree/master