RecyclerView 实现动态添加不同的item模块并自动滑动到屏幕最下端实现

RecyclerView真的强大!
先上效果图,是你要的效果再看:
在这里插入图片描述
先上代码:
展示recyclerview的适配器,在这里适配器我引入的是第三方包装好的框架 万能适配器

//RecyclerViewAdapter 万能适配器框架使用
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'
public class MultipleItemAdapter extends BaseMultiItemQuickAdapter<MyMultipleItem, BaseViewHolder> {

    /**
     * 有参构造函数
     * @param data
     */
    public MultipleItemAdapter(List data) {
        super(data);
        //必须绑定type和layout的关系
        addItemType(MyMultipleItem.FIRST_TYPE, R.layout.test_header);
        addItemType(MyMultipleItem.SECOND_TYPE, R.layout.test_sex);
        addItemType(MyMultipleItem.THIRED_TYPE, R.layout.test_age);
        addItemType(MyMultipleItem.FOURTH_TYPE, R.layout.test_character);
        addItemType(MyMultipleItem.FIVE_TYPE, R.layout.test_hasjob);
        addItemType(MyMultipleItem.SIX_TYPE, R.layout.test_age);
        addItemType(MyMultipleItem.SEVEN_TYPE, R.layout.test_age);
    }

    /**
     * 对应布局的网络数据进行赋值;
     * @param baseViewHolder
     * @param myMultipleItem
     */
    @Override
    protected void convert(@NotNull BaseViewHolder baseViewHolder, MyMultipleItem myMultipleItem) {
        switch (baseViewHolder.getItemViewType()){
            case MyMultipleItem.FIRST_TYPE :
                Logger.e("FIRST_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
            case MyMultipleItem.SECOND_TYPE:
                Logger.e("SECOND_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
            case MyMultipleItem.THIRED_TYPE:
                Logger.e("THIRED_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
            case MyMultipleItem.FOURTH_TYPE:
                Logger.e("FOURTH_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
            case MyMultipleItem.FIVE_TYPE:
                Logger.e("FIVE_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
            case MyMultipleItem.SIX_TYPE:
                Logger.e("SIX_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
            case MyMultipleItem.SEVEN_TYPE:
                Logger.e("SEVEN_TYPE==============="+baseViewHolder.getLayoutPosition());
                break;
        }
    }

    //删除item:
    public void removeItem(int position){
        notifyItemRemoved(position);
    }
}


活动页面的代码:

/**
 * @author : Sugar
 * @action: 职业测试活动页面,利用RecyclerView来进行不同布局的加载;
 * @time : 2020/9/12
 */
public class JobTestActivity extends BaseMvpActivity<JobTestView, JobTestPresenter> implements JobTestView {

    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;
    @BindView(R.id.job_test_text)
    TextView jobTestText;
    @BindView(R.id.job_test_img)
    ImageView jobTestImg;
    @BindView(R.id.job_test_button)
    Button jobTestButton;
    @BindView(R.id.job_test_header)
    LinearLayout jobTestHeader;
    //布局类型的数据列表;
    private List<MyMultipleItem> datas = new ArrayList<>();
    private MultipleItemAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    //判断用户的选择题答案;
    private int sex = -1;
    private int age = -2;
    private int character = -3;
    private int hasjob = -4;
    private int mbit = -5;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ButterKnife.bind(this);
        //初始化recyclerviewAdapter的配置;
        initManager();
    }

    /**
     * 当进入job测试,点击了开始测试按钮;
     * @param view 按钮点击事件
     */
    @OnClick(R.id.job_test_button)
    public void onViewClicked(View view) {
        switch (view.getId()){
            case R.id.job_test_button:
                try {
                    //把first 和 second 布局放到适配器中去;
                    datas.add(new MyMultipleItem(MyMultipleItem.FIRST_TYPE,null));
                    datas.add(new MyMultipleItem(MyMultipleItem.SECOND_TYPE,null));
                    //测试正式
                    useAdapter();
                    //头部隐藏;
                    jobTestHeader.setVisibility(View.GONE);
                    //按钮不再让点击;
                    jobTestButton.setClickable(false);
                }catch (Exception e){
                    Logger.e(""+e);
                }
                break;
            default:
                break;
        }
    }
    @SuppressLint("WrongConstant")
    private void initManager(){
        try {
            //↓↓↓↓↓↓↓↓↓-实例化lienarLayoutManager-↓↓↓↓↓↓↓↓↓\\
            layoutManager = new LinearLayoutManager(this);
            ((LinearLayoutManager) layoutManager).setOrientation(LinearLayoutManager.VERTICAL);
            recyclerView.setLayoutManager(layoutManager);
            //↑↑↑↑↑↑↑↑↑- 以上代码可以对recyclerView进行相关配置 -↑↑↑↑↑↑↑↑↑\\
            adapter = new MultipleItemAdapter(datas);
            //给RecyclerView设置适配器
            recyclerView.setAdapter(adapter);
        }catch (Exception e){
            Logger.e("初始化适配器报错:"+e);
        }
    }
    //点击开始测试按钮;
    private void useAdapter(){
        if(datas.size()>0){
            Logger.e("初始化适配器报错111:"+datas.size());
            adapter.addChildClickViewIds(R.id.sex_boy,R.id.sex_girl,R.id.age_first,R.id.age_second,R.id.age_third,R.id.age_fourth);
            adapter.setOnItemChildClickListener(new OnItemChildClickListener() {
                @Override
                public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
                    switch (view.getId()){
                        case R.id.sex_boy:
                            addItem(sex);
                            sex=1;
                            break;
                        case R.id.sex_girl:
                            addItem(sex);
                            sex=0;
                            break;
                        case R.id.age_first:
                            addItem(age);
                            age=0;
                            break;
                        case R.id.age_second:
                            addItem(age);
                            age=1;
                            break;
                        case R.id.age_third:
                            addItem(age);
                            age=2;
                            break;
                        case R.id.age_fourth:
                            addItem(age);
                            age=3;
                            break;
                    }
                }
            });

        }else {
            Logger.e("初始化适配器报错222:"+datas.size());
        }
    }
    //添加布局
    private void addItem(int hasAdd){
        switch (hasAdd){
            case -1:
                datas.add(new MyMultipleItem(MyMultipleItem.THIRED_TYPE, null));
                break;
            case -2:
                datas.add(new MyMultipleItem(MyMultipleItem.FOURTH_TYPE, null));
                break;
            case -3:

                break;
            case -4:

                break;
            case -5:

                break;
            default:
                break;
        }
        //如果换了选项 hasAdd >= 0;不用添加布局;
        if(hasAdd < 0){
            adapter.notifyDataSetChanged();
            recyclerView.smoothScrollToPosition(adapter.getItemCount()-1);
        }
    }

    @Override
    protected JobTestPresenter createPresenter() {
        return new JobTestPresenter();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_job_test;
    }

    @Override
    protected void initViews() {

    }

    @Override
    public void getJobTest(JobTest jobTest) {

    }

    @Override
    public void showProgressDialog() {

    }

    @Override
    public void hideProgressDialog() {

    }

    @Override
    public void onError(String result) {

    }

    @Override
    public void onNetChange(int netMobile) {

    }

}

因为领导要求是在没有添加模块前,需要展示的信息占不同手机的3/4页面,所以没办法,我就在点击开始按钮的时候把样式添加到第一个模块里面,然后再添加进去要真正需要显示的第一个模块,这么说有点绕口 看一下活动页面的布局你们就明白了:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:id="@+id/job_test_header"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:gravity="center_horizontal"
        android:layout_height="0dp"
        android:layout_weight="3">
        <TextView
            android:id="@+id/job_test_text"
            android:padding="30dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/**"/>
        <ImageView
            android:id="@+id/job_test_img"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:src="@mipmap/job_test"/>
        <Button
            android:id="@+id/job_test_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/qmui_config_color_red"
            android:padding="20dp"
            android:text="开始测试"/>
    </LinearLayout>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
    </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

这回理解了吧,因为如果直接把首先需要展示的活动页面信息放在recyclerview中我没有研究出来怎么控制这个item能够适配不同大小的手机能正好占用手机的3/4位置,所以笨办法就是先写出来,然后点击之后把不需要的布局隐藏,再动态添加到recyclerView中去:

//把first 和 second 布局放到适配器中去;
                    datas.add(new MyMultipleItem(MyMultipleItem.FIRST_TYPE,null));
                    datas.add(new MyMultipleItem(MyMultipleItem.SECOND_TYPE,null));
                    //测试正式
                    useAdapter();
                    //头部隐藏;
                    jobTestHeader.setVisibility(View.GONE);
                    //按钮不再让点击;
                    jobTestButton.setClickable(false);

然后需要说的一点是
adapter.addChildClickViewIds(R.id.sex_boy,R.id.sex_girl,R.id.age_first,R.id.age_second,R.id.age_third,R.id.age_fourth);
**这句话很重要,**网上关于万能适配器的说明很久以前的了我参照他们的写后发现,动态添加的布局里面的控件点击事件不好用了(也是尝试了好久);最后添加这句话后解决!

达到添加的布局直接在手机的最下方依靠一句代码:
//如果换了选项 hasAdd >= 0;不用添加布局;
if(hasAdd < 0){
adapter.notifyDataSetChanged();
recyclerView.smoothScrollToPosition(adapter.getItemCount()-1);
}

recyclerView.smoothScrollToPosition(adapter.getItemCount()-1); —》可以直接让新添加的布局显示在手机的最下方;

随手把我写的测试布局也都放上吧:

在这里插入图片描述
test_age.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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="第2项/共4项回答"/>
    </LinearLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <com.makeramen.roundedimageview.RoundedImageView
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:src="@mipmap/job_test"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@+id/text_age"
            android:layout_marginRight="30dp"
            />
        <TextView
            android:id="@+id/text_age"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="你的年龄?"/>
    </RelativeLayout>
    <LinearLayout
        android:paddingBottom="30dp"
        android:paddingTop="30dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center">
        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <RadioButton
                android:id="@+id/age_first"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:button="@null"
                android:buttonTintMode="screen"
                android:drawableRight="@android:drawable/btn_radio"
                android:text="a. 18岁以下"/>
            <RadioButton
                android:id="@+id/age_second"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:button="@null"
                android:buttonTintMode="screen"
                android:drawableRight="@android:drawable/btn_radio"
                android:text="b. 18-25岁"/>
            <RadioButton
                android:id="@+id/age_third"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:button="@null"
                android:buttonTintMode="screen"
                android:drawableRight="@android:drawable/btn_radio"
                android:text="c. 25-35岁"/>
            <RadioButton
                android:id="@+id/age_fourth"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:button="@null"
                android:buttonTintMode="screen"
                android:drawableRight="@android:drawable/btn_radio"
                android:text="d. 35岁以上"/>
        </RadioGroup>
    </LinearLayout>
</LinearLayout>

懒了,就放着一个吧,其实其它的大体都一样,你们可以自己设置不同的布局;
小白写博客,自己记录自己用,如果对你正好有帮助那就最好不过了

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值