Android中骨架屏(Skeleton Screen)使用

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总体使用上来说还是比较简单的.

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Unknown world

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值