为什么RecyclerView.OnScrollListener()仅影响recyclerview的最后一项

时间:2016-12-21 09:24:49

标签: java android android-recyclerview

我想在我的应用程序中使用此功能

enter image description here

意味着当RecyclerView滚动时,TextView显示时间应该出现并在一小段时间之后消失,我的努力就是这样,目标TextView有Visiblity.GONE和适配器看起来像

public class ChatMessageAdapter extends RecyclerView.Adapter<ViewHolder> {

    private List<ChatMessage> mMessageList;
    private Context mContext;
    private boolean isMe = false;

    private ThemMessageHolder messageHolder;

    public ChatMessageAdapter(Context mContext, List<ChatMessage> mMessageList){
        this.mContext = mContext;
        this.mMessageList = mMessageList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View rootView = LayoutInflater.from(mContext).inflate( R.layout.chat_them_container, parent, false );
        return new ThemMessageHolder(rootView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        messageHolder = (ThemMessageHolder) holder;
        messageHolder.mMessageTextView.setText(mMessageList.get(position).getMessage());
        messageHolder.mSentAtTextView.setText(mMessageList.get(position).getSentAt());
    }

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

    public void showAndHideDate(){
        messageHolder.mSentAtTextView.setVisibility(View.VISIBLE);
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                messageHolder.mSentAtTextView.setVisibility(View.GONE);
            }
        },3500);

    }

}

在MainActivity中我只是

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);        

        mMessageList = new CopyOnWriteArrayList<>();

        mChatMessagesRecyclerView = (RecyclerView) findViewById(R.id.chat_msg_rv);
        mChatMessagesRecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        mChatMessageAdapter = new ChatMessageAdapter(MainActivity.this, mMessageList);
        mChatMessagesRecyclerView.setAdapter(mChatMessageAdapter);

        mChatMessagesRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                mChatMessageAdapter.showAndHideDate(); // Here I'm calling the method defined in Adapter class
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });
    }

通过上面的代码我只对RecyclerView的最后一项产生了所需的效果,如图所示

enter image description here

如何对RecyclerView的所有项目应用所需效果?

1 个答案:

答案 0 :(得分:2)

问题是你在适配器中只有一个ThemMessageHolder变量。意味着变量被每onBindViewHolder()次调用所覆盖。然后,messageHolder将指向最后创建的持有者,而showAndHideDate()仅适用于它。

解决方案可以找到所有可见的持有者(伪代码):

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (initChatBarUI()){
            mSendImageButton.setOnClickListener(MainActivity.this);
            mEmoImageButton.setOnClickListener(MainActivity.this);
        }

        mMessageList = new CopyOnWriteArrayList<>();

        final LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
        mChatMessagesRecyclerView = (RecyclerView) findViewById(R.id.chat_msg_rv);
        mChatMessagesRecyclerView.setLayoutManager(layoutManager);
        mChatMessageAdapter = new ChatMessageAdapter(MainActivity.this, mMessageList);
        mChatMessagesRecyclerView.setAdapter(mChatMessageAdapter);

        mChatMessagesRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                final int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
                final int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
                mChatMessageAdapter.showAndHideDate(mChatMessagesRecyclerView, firstVisibleItemPosition, lastVisibleItemPosition); // Here I'm calling the method defined in Adapter class
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });   
    }

和showAndHideDate()可能看起来像

public void showAndHideDate(RecyclerView mRecyclerView, int firstVisibleItemPosition, int lastVisibleItemPosition){

    for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; ++i) {
        final ThemMessageHolder holder = (ThemMessageHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
        holder.mSentAtTextView.setVisibility(View.VISIBLE);
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                holder.mSentAtTextView.setVisibility(View.GONE);
            }
        },3500);
    }       

}