安卓仿陌陌用户详情页轮播图联动效果

 代码是写在fragment中 所以需要创建fragmet 也可以复制到activity中使用

public class SquareFragment extends Fragment{

    //加载view
    private View view;
    private SquareFragmentPersenter squareFragmentPersenter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = LayoutInflater.from(getContext()).inflate(R.layout.square_fragment,null);
        squareFragmentPersenter = new SquareFragmentPersenter(view,getContext(),getActivity());
        return view;
    }

}

实体bean类

public class TestDetailBean {

    /**
     * int : imageId
     * boolean : isSelect
     */

    private List<DataBean> data;

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {
        private Integer imageId;

        private boolean isSelect;

        public Integer getImageId() {
            return imageId;
        }

        public void setImageId(Integer imageId) {
            this.imageId = imageId;
        }

        public boolean isSelect() {
            return isSelect;
        }

        public void setSelect(boolean select) {
            isSelect = select;
        }
    }
}

对应于fragment中创建的persenter类

public class SquareFragmentPersenter implements UserDetailRecAdapter.OnItemClickListener{

    private View view;
    private Context context;
    private Activity activity;

    //recyclerview
    private RecyclerView detailRec;
    private ViewPager detailViewPager;
    private List<Integer> list = new ArrayList<>();
    private UserDetailBannerAdapter detailBannerAdapter;
    private UserDetailRecAdapter detailRecAdapter;
    private TestDetailBean.DataBean testDetailBean;
    private List<TestDetailBean.DataBean> recList = new ArrayList<>();


    public SquareFragmentPersenter(View sview, Context scontext, Activity sactivity) {
        this.view = sview;
        this.context = scontext;
        this.activity = sactivity;
        initLayoutId();
    }

    //初始化id
    public void initLayoutId() {
        detailViewPager = view.findViewById(R.id.user_detail_viewpager);
        detailRec = view.findViewById(R.id.user_detail_rec);
        initData();
    }

    //初始化数据
    public void initData() {
        for (int i = 0; i < 10; i++) {
            list.add(R.drawable.test);
        }

        detailBannerAdapter = new UserDetailBannerAdapter(context, list);
        detailViewPager.setAdapter(detailBannerAdapter);
        detailViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
//                MageLog.e("chrn", "当前 position = " + position);
                for (int i = 0; i < recList.size(); i++) {
                    if (i == position) {
                        recList.get(i).setSelect(true);
                        //设置位置
                        detailRec.smoothScrollToPosition(i);
                    } else {
                        recList.get(i).setSelect(false);
                    }
                }
                detailRecAdapter.notifyDataSetChanged();

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        for (int i = 0; i < 10; i++) {
            testDetailBean = new TestDetailBean.DataBean();
            testDetailBean.setImageId(R.drawable.test);
            if (i == 0) {
                testDetailBean.setSelect(true);
            } else {
                testDetailBean.setSelect(false);
            }
            recList.add(testDetailBean);
        }


        CenterLayoutManager manager = new CenterLayoutManager(context);
        manager.setOrientation(RecyclerView.HORIZONTAL);
        detailRecAdapter = new UserDetailRecAdapter(context, recList,this);
        detailRec.setLayoutManager(manager);
        detailRec.setAdapter(detailRecAdapter);




//        MageLog.e("chrn", recList.size() + "-----");

        for (int i = 0; i < recList.size(); i++) {
            MageLog.e("chrn", recList.get(i).isSelect() + "---" + i);
        }


    }


    @Override
    public void onClick(int i) {
        detailViewPager.setCurrentItem(i);
        detailRec.smoothScrollToPosition(i);
    }

}

下面这段代码是解决根本问题的 也就是recyclerview设置位置会出现闪动的问题 值得参考

/*
 * Author : Chen
 * Date : 2021-03-02
 * Time : 17:27
 * Email : Libertyed@163.com
 * smoothScrollToPosition
 * 自定义 layoutmanger 解决 recycler 默认 layoutmanger 方法 smoothScrollToPosition 调用时闪动的问题
 */

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;

public class CenterLayoutManager extends LinearLayoutManager {

    public CenterLayoutManager(Context context) {
        super(context);
    }

    public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private static class CenterSmoothScroller extends LinearSmoothScroller {

        public CenterSmoothScroller(Context context) {
            super(context);
        }

        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }

        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            //这里默认layoutmanger是20f 会出现闪动问题
            return 100f / displayMetrics.densityDpi;
        }
    }

}

适配器 adapter 里面

public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List payloads) 

这个方法 可以自己去查然后了解下

public class UserDetailRecAdapter extends RecyclerView.Adapter {

    private Context context;
    private List<TestDetailBean.DataBean> list;
    private static final int TRUE_TYPE = 1;
    private static final int FALSE_TYPE = 2;
    private OnItemClickListener listener;

    public UserDetailRecAdapter(Context context, List<TestDetailBean.DataBean> list, OnItemClickListener listener) {
        this.context = context;
        this.list = list;
        this.listener = listener;
    }

    @Override
    public int getItemViewType(int position) {
        if (list.get(position).isSelect()) {
            MageLog.e("chrn", "当前 select 状态" + list.get(position).isSelect() + "---positon" + position);
            return TRUE_TYPE;
        } else {
            MageLog.e("chrn", "当前 select 状态" + list.get(position).isSelect() + "---positon" + position);
            return FALSE_TYPE;
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = null;
        RecyclerView.ViewHolder holder = null;
//        MageLog
        switch (viewType) {
            case TRUE_TYPE:
                view = LayoutInflater.from(context).inflate(R.layout.user_detail_rec_adapter_true_image, null);
                holder = new ViewHolderTrue(view);
                break;
            case FALSE_TYPE:
                view = LayoutInflater.from(context).inflate(R.layout.user_detail_rec_adapter_false_image, null);
                holder = new ViewHolderFalse(view);
                break;
        }
        return holder;

    }


    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
        } else {
            if (holder instanceof ViewHolderTrue) {
                Glide.with(context).load(list.get(position).getImageId()).apply(RequestOptions.bitmapTransform(new CircleCrop())).into(((ViewHolderTrue) holder).imageTrue);
                ((ViewHolderTrue) holder).imageTrue.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        listener.onClick(position);
                    }
                });
            } else {
                Glide.with(context).load(list.get(position).getImageId()).into(((ViewHolderFalse) holder).imageFalse);
                ((ViewHolderFalse) holder).imageFalse.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        listener.onClick(position);
                    }
                });
            }
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ViewHolderTrue) {
            Glide.with(context).load(list.get(position).getImageId()).apply(RequestOptions.bitmapTransform(new CircleCrop())).into(((ViewHolderTrue) holder).imageTrue);
            ((ViewHolderTrue) holder).imageTrue.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onClick(position);
                }
            });
        } else {
            Glide.with(context).load(list.get(position).getImageId()).into(((ViewHolderFalse) holder).imageFalse);
            ((ViewHolderFalse) holder).imageFalse.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onClick(position);
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class ViewHolderFalse extends RecyclerView.ViewHolder {
        private final ImageView imageFalse;

        public ViewHolderFalse(@NonNull View itemView) {
            super(itemView);
            imageFalse = itemView.findViewById(R.id.user_detail_rec_image_false);
        }

    }


    public class ViewHolderTrue extends RecyclerView.ViewHolder {

        private final ImageView imageTrue;

        public ViewHolderTrue(@NonNull View itemView) {
            super(itemView);
            imageTrue = itemView.findViewById(R.id.user_detail_rec_image_true);
        }
    }

    public interface OnItemClickListener {
        void onClick(int i);
    }

}

接下来就是布局文件   square_fragment.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="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp">

        <androidx.viewpager.widget.ViewPager
            android:background="@color/color_99CFFF"
            android:id="@+id/user_detail_viewpager"
            android:layout_width="match_parent"
            android:layout_height="300dp">

        </androidx.viewpager.widget.ViewPager>

        <LinearLayout
            android:layout_alignParentBottom="true"
            android:background="@color/f_FF0D0D_translucent_49"
            android:layout_width="match_parent"
            android:layout_height="120dp"
            android:gravity="center_vertical">

            <androidx.recyclerview.widget.RecyclerView
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:id="@+id/user_detail_rec"
                android:background="@color/primary"
                android:layout_width="match_parent"
                android:layout_height="80dp">

            </androidx.recyclerview.widget.RecyclerView>

        </LinearLayout>

    </RelativeLayout>



</LinearLayout>

user_detail_rec_adapter_false_image.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_marginLeft="10dp"
        android:id="@+id/user_detail_rec_image_false"
        android:layout_width="80dp"
        android:layout_height="80dp">

    </ImageView>

</LinearLayout>

user_detail_rec_adapter_true_image.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_marginLeft="10dp"
        android:id="@+id/user_detail_rec_image_true"
        android:layout_width="80dp"
        android:layout_height="80dp">

    </ImageView>

</LinearLayout>

到这 基本就是完成了 因为项目不需要类似于陌陌的放大动画效果 所以没有写 这里只是提供分享 使用没有问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值