Android中骨架屏(Skeleton Screen)使用
1.什么是骨架屏
页面在没有完全渲染完成之前,用户会看到一个占位的样式,用以描绘了当前页面的大致框架,加载完成后,最终骨架屏中各个占位部分将被真实的数据替换。
效果图如下:
2.Android中使用Skeleton Screen
1.引入依赖
//骨架 skeleton
implementation 'com.ethanhua:skeleton:1.1.2'
implementation 'io.supercharge:shimmerlayout:2.1.0'
2.skeleton载预览函数说明(源码)
/**
* Created by ethanhua on 2017/7/29.
*/
public class Skeleton {
public static RecyclerViewSkeletonScreen.Builder bind(RecyclerView recyclerView) {
return new RecyclerViewSkeletonScreen.Builder(recyclerView);
}
public static ViewSkeletonScreen.Builder bind(View view) {
return new ViewSkeletonScreen.Builder(view);
}
}
3. 作用于RecycleView
- bind //绑定的RecycleView,不要给RecycleView设置adapter
- adapter //设置Skeleton消失时要给RecycleView设置的 adapter,内部会自动绑定
- load //预览加载的RecycleView item 布局文件
- shimmer(true) // 是否显示shimmer动画,默认显示
- count(10) // 设置recycleView 默认预览加载条目数,默认10
- color(color) // shimmer 动画颜色,默认 #a2878787
- angle(20) //shimmer 动画角度,默认 20度
- duration(1000) // shimmer动画持续时间 ,默认1000ms;
- frozen(true) // skeleton 显示时是否RecycleView 可滑动,默认不可滑动
- hide // 关闭Skeleton,就会自动绑定Adapter,显示真正数据
skeletonScreen = Skeleton.bind(mRecycleView)
.adapter(mAdapter)
.shimmer(true)
.angle(20)
.frozen(false)
.duration(3000)
.color(R.color.shimmer_color)
.count(5)//default count is 10
.load(R.layout.recycle_item)
.show();
4.作用于View
- bind 绑定view
- load 预览加载的View 布局,会替换绑定view内的view
- shimmer(true) // 是否显示shimmer动画,默认显示
- color(color) // shimmer 动画颜色,默认 #a2878787
- angle(20) //shimmer 动画角度,默认 20度
- duration(1000) // shimmer动画持续时间 ,默认1000ms;
- hide // 关闭Skeleton 加载预览,显示真正View
skeletonScreen = Skeleton.bind(mView)
.load(R.layout.view_layout)
.shimmer(true)
.angle(20)
.duration(2000)
.color(R.color.c_bf)
.show();
示例代码
CommonAdaper编写
public class CommonAdaper extends RecyclerView.Adapter<CommonViewHolder> {
private List<Home> mList;
private Context mContext;
public CommonAdaper(List<Home> mList, Context context) {
this.mList = mList;
this.mContext = context;
}
public void updateDate(List<Home> list){
this.mList = list;
}
@NonNull
@Override
public CommonViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//加载布局
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item,parent,false);
CommonViewHolder viewHolder = new CommonViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull CommonViewHolder holder, int position) {
//绑定赋值 操作item的方法
holder.tvName.setText(mList.get(position).getName());
holder.tvAge.setText(mList.get(position).getAge());
holder.tvNote.setText(mList.get(position).getNote());
}
@Override
public int getItemCount() {
return mList==null?0:mList.size();
}
}
CommonViewHolder编写
public class CommonViewHolder extends RecyclerView.ViewHolder {
public TextView tvName;
public TextView tvAge;
public TextView tvNote;
public CommonViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_name);
tvAge = itemView.findViewById(R.id.tv_age);
tvNote = itemView.findViewById(R.id.tv_note);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private RecyclerView rvList;
private CommonAdaper commonAdaper;
private List<Home> homes;
private RecyclerViewSkeletonScreen skeletonScreen;
private static final int MSG_CODE = 1000;
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
switch (msg.what){
case MSG_CODE:{
Toast.makeText(MainActivity.this, "页面开始加载数据", Toast.LENGTH_SHORT).show();
System.out.println(homes);
commonAdaper.updateDate(homes);
commonAdaper.notifyDataSetChanged();
skeletonScreen.hide();
break;
}
}
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
rvList = (RecyclerView) findViewById(R.id.rv_list);
commonAdaper = new CommonAdaper(homes,this);
homes = new ArrayList<>();
rvList.setLayoutManager(new LinearLayoutManager(this));
rvList.setAdapter(commonAdaper);
skeletonScreen = Skeleton.bind(rvList)
.shimmer(true)
.count(5)
.adapter(commonAdaper)
.load(R.layout.load_item)
.duration(3000)
.color(R.color.colorAccent)
.show();
getDate();
}
private void getDate(){
new Thread(new Runnable() {
@Override
public void run() {
try {
//模拟网络获取数据
Thread.sleep(5000);
homes.clear();
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
homes.add(new Home("名字:小A","年龄:20","描述:我是一名android工程师"));
mHandler.sendEmptyMessage(MSG_CODE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
MainActivit的布局文件
<?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:orientation="vertical"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rv_list">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
Item的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="20dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv_icon"
android:src="@mipmap/ic_launcher"
android:layout_marginRight="20dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView
android:layout_width="100dp"
android:layout_height="20dp"
android:layout_toRightOf="@+id/iv_icon"
android:id="@+id/tv_name"/>
<TextView
android:layout_width="120dp"
android:layout_height="20dp"
android:id="@+id/tv_age"
android:layout_toRightOf="@+id/iv_icon"
android:layout_marginTop="10dp"
android:layout_below="@+id/tv_name"/>
<TextView
android:layout_width="130dp"
android:layout_height="20dp"
android:layout_toRightOf="@+id/iv_icon"
android:id="@+id/tv_note"
android:layout_marginTop="10dp"
android:layout_below="@+id/tv_age"/>
</RelativeLayout>
skeleton的预加载的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="20dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv_icon"
android:src="@mipmap/ic_launcher"
android:layout_marginRight="20dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView
android:layout_width="100dp"
android:layout_height="20dp"
android:background="@color/c_bf"
android:layout_toRightOf="@+id/iv_icon"
android:id="@+id/tv_name"/>
<TextView
android:layout_width="120dp"
android:layout_height="20dp"
android:background="@color/c_bf"
android:id="@+id/tv_age"
android:layout_toRightOf="@+id/iv_icon"
android:layout_marginTop="10dp"
android:layout_below="@+id/tv_name"/>
<TextView
android:layout_width="130dp"
android:layout_height="20dp"
android:background="@color/c_bf"
android:layout_toRightOf="@+id/iv_icon"
android:id="@+id/tv_note"
android:layout_marginTop="10dp"
android:layout_below="@+id/tv_age"/>
</RelativeLayout>
Home模型类
public class Home implements Serializable {
private String name;
private String age;
private String note;
public Home(String name, String age, String note) {
this.name = name;
this.age = age;
this.note = note;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
@Override
public String toString() {
return "Home{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", note='" + note + '\'' +
'}';
}
}
总结
Skeleton总体使用上来说还是比较简单的.
转载:https://blog.csdn.net/qq_36573702/article/details/106108731
查看评论