Android实现recyclerview吸顶功能

   最近在做需求的时候遇到了这样的一个问题,需要完成一个recyclerview的吸顶效果的功能,一开始的提供的方案是,去监听需要进行吸顶吸顶功能的位置,然后根据这个具体的位置的信息来判断是否进行吸顶效果的逻辑。总感觉这样实现有点问题,感觉有点不太好实现,于是去看了好多别人的实现,感觉和自己的需求不太满足。找了一上午没有确定下来最终的方案,于是到了中午去吃饭回来的做电梯回工位的时候,突然有了思路。先大概的说一下这个思路吧,实现吸顶效果无非就是两个view交替的显示,在显示的时候另一个隐藏的效果。废话不多说先看效果图:

一般的需要吸顶的view是隐藏在这个activity的最顶部的,在recycler的item中还有与之对应的view,当item中的view和最顶部的position相等且顶部的position大于当前的item的view时就显示否则就隐藏,这个是实现整个效果的核心点。上代码,我尽可能的将代码整全。

首先我们需要创建一个recyclerview的效果,先看recyclerview所在的activity的xml代码

test_activity:




    

        
    

    


将吸顶效果的view进行隐藏

接着看一下recyclerview对应的item的xml代码

tem_test.xml:




    

        

    


    

        

        
    


同样的将对应的view进行隐藏

接下来是逻辑代码,写一个测试用的recyclerview的bean类

TestBean:

package com.example.mytestproject;

/**
 * @describe:
 * @created 2021/8/1
 */
public class TestBean {
    String context1;
    String context2;

    public String getContext1() {
        return context1;
    }

    public String getContext2() {
        return context2;
    }

    public void setContext1(String context1) {
        this.context1 = context1;
    }

    public void setContext2(String context2) {
        this.context2 = context2;
    }
}

接下来写一下他对应的adapter

MyTestAdapter:

package com.example.mytestproject;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @describe:
 * @created 2021/8/1
 */
public class MyTestAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private List mList;

    public MyTestAdapter(Context context, List list) {
        this.mContext = context;
        this.mList = list;
    }

    @NonNull
    @NotNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_test, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull RecyclerView.ViewHolder holder, int position) {
        ViewHolder viewHolder = (ViewHolder) holder;
        viewHolder.mTvContext1.setText(mList.get(position).getContext1());
        viewHolder.mTvContext2.setText(mList.get(position).getContext2());
        if (position == 10) {
            //设定吸顶view的显示地方,这里我写好10,可以根据具体哦的业务需求向外暴露这个position值
            viewHolder.mLlTest.setVisibility(View.VISIBLE);
        }

    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView mTvContext1, mTvContext2;
        LinearLayout mLlTest;

        public ViewHolder(@NonNull @NotNull View itemView) {
            super(itemView);
            mTvContext1 = itemView.findViewById(R.id.tv_context1);
            mTvContext2 = itemView.findViewById(R.id.tv_context2);
            mLlTest = itemView.findViewById(R.id.ll_test);
        }
    }
}

recyclerview的adapter的大多数方法就不具体的分析了,其中主要是显示那个item的地方需要注意,可以根据自己的业务来向外暴露一个position的值,这里我就写死了。同时,我建议可以使用eventbus的方式将这个值传入到activity中进行逻辑的判断。

接下来是Activity的逻辑:

MyTestActivity:

package com.example.mytestproject;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class MyTestActivity extends AppCompatActivity {
    RecyclerView mRvTest;
    LinearLayout mLlTest;
    MyTestAdapter myTestAdapter;
    List testBeans = new ArrayList<>();
    TestBean testBean;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
        setData(testBeans);
        initRecyclerView();
    }

    private void initView() {
        mRvTest = findViewById(R.id.rv_test);
        mLlTest = findViewById(R.id.ll_test);
    }

    private void initRecyclerView() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRvTest.setLayoutManager(linearLayoutManager);
        myTestAdapter = new MyTestAdapter(this, testBeans);
        mRvTest.setAdapter(myTestAdapter);
        mRvTest.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull @NotNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                /**
                 *获取最顶部position的位置
                 */
                int topPosition = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
                if (dy > 0 && topPosition > 10) {
                    /**
                     * dy > 0是向上滑动,dy < 0 是下滑动
                     */
                    mLlTest.setVisibility(View.VISIBLE);
                    Log.d("上下滑", String.valueOf(dy).toString());
                } else if (dy < 0 && topPosition <= 10) {
                    mLlTest.setVisibility(View.GONE);
                    Log.d("上下滑", String.valueOf(dy).toString());
                }

            }
        });

    }

    private void setData(List testBeans) {
        testBean = new TestBean();
        for (int i = 0; i < 100; i++) {
            testBean.setContext1("item左内容");
            testBean.setContext2("item右内容");
            testBeans.add(testBean);
        }
    }
}

在activity中获取顶部的position,与adapter中需要显示的view进行判断,如果最顶部的position大于他就显示,同时为了显示效果更好,还进行监听recycler的滑动状态根据滑动的状态来进行判断当前的位置是否显示。总之,感觉这样实现能完成需求,但是感觉不太好,希望有好的方案可以私信我。

你可能感兴趣的:(Android需求总结,android)