简单实现仿某宝地址选择三级联动样式

本文介绍如何在Android中使用RecyclerView实现类似某宝的三级联动地址选择效果,包括动画的添加和间距设置。通过自定义Adapter和ItemDecoration,实现上拉动画效果,并解决了间距问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容简介

简单看一下需要实现的效果,如图:
这里写图片描述

实现步骤

第一步 找准方向

其实就是想好要用recyclerview而不是listview。如果要问我recyclerview是什么的话。。

第二步 开干

首先需要先在xml里放置这么个控件

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_main">
</android.support.v7.widget.RecyclerView>

这里我加了一个背景,背景也可以在它的父布局加,主要是作为动画的时候下面的颜色(颜色为一种灰色)。

然后,需要编写每个item的布局,这里也非常简单,还是贴一下代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="1dp"
    android:background="@color/white"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:paddingLeft="5dp"
        android:text="辽宁"
        android:textColor="@android:color/black" />

    <ImageView
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:padding="3dp"
        android:src="@mipmap/ic_right" />
</LinearLayout>

注意这里的每个item的背景我都设置成了白色,这样的话就能和背景色区分开。

接下来需要编写adapter了,也就是recycler的adapter,这里比较关键:

public class CheckProvAdapter extends RecyclerView.Adapter<CheckProvAdapter.CheckProvViewHolder> {
    private Context context;
    private int i = 0;

    public CheckProvAdapter(Context context) {
        this.context = context;
    }

    @Override
    public CheckProvViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = View.inflate(context,R.layout.item_check_prov,null);
        v.setLayoutParams(new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        CheckProvViewHolder viewHolder = new CheckProvViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(CheckProvViewHolder holder, int position) {
        if(position>i){
            //上滑
            ObjectAnimator.ofFloat(holder.itemView, "translationY", holder.itemView.getMeasuredHeight(), 0).setDuration(300).start();
        }else {
            //下滑
        }
        i=position;
        holder.tv.setText("辽宁");
    }

    @Override
    public int getItemCount() {
        return 100;
    }

    public static class CheckProvViewHolder extends RecyclerView.ViewHolder {
        TextView tv;
        public CheckProvViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }
    }

}

关键部分为onBindViewHolder()这个方法,在这里为itemview添加动画并播放,这里还有个小猫腻,就是怎么来判断是向上滑还是向下滑呢,这里我是根据position的增加或减少情况来判断的,没想到有什么其他的更加完美的方法。
这样,我们在上拉的时候来添加动画并播放。adapter完成,接下来给recyclerview set上:

recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
recyclerview.setLayoutManager(new LinearLayoutManager(this));
recyclerview.setAdapter(new CheckProvAdapter(this));

好的,这时候效果基本上已经出来了,但是还有点小瑕疵,因为没有间距,说好的像listview一样的间距呢,我表示不会,于是各种百度google,大神们说重写ondraw方法就好了。我想了一下,我只是要个间距而已,难道间距需要用画的么?于是我想了个可能是最简单的recylerview加间距的方法:

public class LinearLayoutManagerDivider extends RecyclerView.ItemDecoration {
    private int height;

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c,parent,state);
    }

    public LinearLayoutManagerDivider(int i) {
        super();
        height = i;//构造方法中传入要设置的间距高度
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.set(0,0,0,height);//最关键的一步,在这里加间距,height为间距的高度
    }
}

这个东西叫做RecyclerView.ItemDecoration,其中重写的getItemOffsets看名字是来拿到item的偏移量的,因为如果画了分隔线的话那item肯定会有偏移的嘛,如果我不画分割线,只偏移呢,那不就是传说中的间距么。。ok,就一句话:

outRect.set(0,0,0,height);

然后给recycler放上呗:

recyclerview.addItemDecoration(new LinearLayoutManagerDivider(dp2px(1)));
recyclerview.setHasFixedSize(true);

因为我们是固定大小的,所以加上setHasFixedSize(true)这个方法来提高我们的效率。
好了到这里所有的效果就已经实现了。

总结

两个事,一动画,二间距,动画可以加在onBindViewHolder方法里,而且动画效果可以叠加;间距呢,刚才的方法outRect.set()方法,四个参数分别是left,top,right,bottom,不用我说这回也知道这个方法以后该怎么理解了

还是题外话

以前一直没有认真研究recyclerview,因为觉得listview已经很强大了,基本满足工作中的所有需求了,而且看网上的博客也好还是demo也好,总感觉这玩楞真复杂,太难了。但是咱要始终是要进步啊,所以就抽时间看了看官方文档,发现也没有自己想象中的那么难,而且当初看到这个效果的时候首先想到的是在github上的一个库,这里的基本思路也是参考这个recyclerview-animators这个库很方便,但是美中不足的是不能实现上图中那种只有上拉的时候有动画,在下拉的时候没有动画,所以才有了小弟的这个方法。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值