簡體   English   中英

Android:Recycler 視圖的 UI 在項目點擊時不會改變?

[英]Android: Recycler view's UI doesn't change on item click?

當我單擊該項目時,我試圖更改回收站視圖項目的背景。 數據實際上已更改,但 UI 沒有更改。 我嘗試了很多嘗試不同的方法,但沒有任何效果。 雖然我正在調用 notifyItemChanged() 但它沒有用。

任何讓這件事工作的解決方案都會非常有幫助。

**我的代碼:**

@Override
    public void onBindViewHolder(@NonNull final ViewHolder viewHolder, final int i) {


        customNoteView = notesList.get(i);
        notesText = viewHolder.notesWriteArea;
        notesImage = viewHolder.notesImage;
        notesAudio = viewHolder.notesAudio;
        notesAudioPlayButton = viewHolder.notesAudioPlayButton;
        notesAudioSeekBar = viewHolder.notesAudioSeekBar;
        notesAudioDeleteButton = viewHolder.notesAudioDeleteButton;



        if(customNoteView.getNoteText()!=null){
            editTextList.add(notesText);
            notesText.setVisibility(View.VISIBLE);
            notesImage.setVisibility(View.GONE);
            notesAudio.setVisibility(View.GONE);
            notesText.requestFocus();
            focussedEditText = notesText;
            notesText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View view, boolean b) {
                    if(b){
                        focussedEditText = ((CustomEditText)view);
                        //Toast.makeText(context, ((CustomEditText) view).getText().toString(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
        else if(customNoteView.getImageUri()!=0){
            notesImage.setVisibility(View.VISIBLE);
            notesText.setVisibility(View.GONE);
            notesAudio.setVisibility(View.GONE);
            Glide.with(notesImage.getContext())
                    .load(notesImage.getContext().getDrawable(customNoteView.getImageUri()))
                    .into(notesImage);

            notesImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(context, FullScreen.class);
                    ActivityOptionsCompat options =  ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context,
                            notesImage,
                            ViewCompat.getTransitionName(notesImage)
                            );

                    context.startActivity(intent, options.toBundle());

                }
            });
        }
        else if(customNoteView.getAudioUri()!=null){
            notesAudio.setVisibility(View.VISIBLE);
            notesImage.setVisibility(View.GONE);
            notesText.setVisibility(View.GONE);
            notesAudioPlayButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    notesAudioPlayButton.setBackground(context.getDrawable(R.drawable.ic_pause));
                    notesAudio.setBackground(context.getDrawable(R.drawable.gray_rectangular_background));
                    notifyItemChanged(viewHolder.getAdapterPosition());

                    Toast.makeText(context, ""+viewHolder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
                }
            });

        }

    }

最后,我設法找到了我自己問題的答案以及沒有 UI 更改的根本原因。

錯誤:

我實際上是在onBindViewHolder(...)方法中設置點擊偵聽器。

解決方案:

如果您想在嘗試更新點擊事件上的回收器視圖時避免notifyItemChanged(position)和其他東西,那么您應該在 viewHolder 類而不是onBindViewHolder設置點擊偵聽onBindViewHolder

PS:應用此更改對我來說效果很好。@Blind Kai 的解決方案也有效,但需要刷新視圖。 我很確定這個更容易和高效。不過我很欣賞他的努力。

如果你想獲得這種類型的行為,你可以嘗試在你的類中添加字段,並在你每次在onBindViewHolder方法中綁定項目時檢查它:

if (current.isClicked) {
    viewHolder.itemView.setBackgroundColor(*needed_color*);
} else {
    viewHolder.itemView.setBackgroundColor(*default_color*);
}

viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        current.isClicked = !current.isClicked;
        notifyItemChanged(viewHolder.getAdapterPosition());
    }
});
  • current - 在列表中i位置的項目;

  • itemView - 項目的根視圖;

    如果您需要更多詳細信息,請隨時提問和評論。 (答案被編輯和清理了幾次)

試試下面的代碼:

1) MainActivity.class:

public class MainActivity extends AppCompatActivity {

private final String TAG = MainActivity.class.getSimpleName();
private RecyclerView rv;

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

    rv = (RecyclerView) findViewById(R.id.rv);
    rv.setLayoutManager(new LinearLayoutManager(MainActivity.this));
    List<String> data = new ArrayList<>();
    List<Boolean> selection_states = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        data.add("Item " + (i + 1));
        selection_states.add(false);
    }
    rv.setAdapter(new MyRecyclerViewAdapter(MainActivity.this, data, selection_states));
}

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    private List<String> mData;
    private List<Boolean> mSelectionStates;
    private LayoutInflater mInflater;

    MyRecyclerViewAdapter(Context context, List<String> data, List<Boolean> selection_states) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
        this.mSelectionStates = selection_states;
    }

    @Override
    @NonNull
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recycler_view_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {

        holder.tv.setText(mData.get(position));

        holder.ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                int previous_selected = -1;
                for (int i = 0; i < getSelectionStates().size(); i++) {
                    if (getSelectionStates().get(i)) {
                        previous_selected = i;
                        break;
                    }
                }
                if (previous_selected == -1) { // nothing is selected
                    setSelectionState(position, true);
                    notifyItemChanged(position);
                } else if (previous_selected != position) { // selected (other than current selected)
                    setSelectionState(previous_selected, false);
                    setSelectionState(position, true);
                    notifyItemChanged(previous_selected);
                    notifyItemChanged(position);
                }
            }
        });

        if (mSelectionStates.get(position)) {
            //Log.i(TAG, "Select " + position);
            holder.ll.setBackgroundColor(ContextCompat.getColor(MainActivity.this, android.R.color.holo_red_dark));
        } else {
            //Log.i(TAG, "De-Select " + position);
            holder.ll.setBackgroundColor(ContextCompat.getColor(MainActivity.this, android.R.color.white));
        }

    }

    private List<Boolean> getSelectionStates() {
        return mSelectionStates;
    }

    private void setSelectionState(int position, boolean state) {
        mSelectionStates.set(position, state);
    }

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


    private class ViewHolder extends RecyclerView.ViewHolder {
        final LinearLayout ll;
        final TextView tv;

        ViewHolder(View itemView) {
            super(itemView);
            ll = (LinearLayout) itemView.findViewById(R.id.ll);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }

    }

}

}

2)activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rv">
</androidx.recyclerview.widget.RecyclerView>

</RelativeLayout>

3)recycler_view_item.xml:

<?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:padding="20dp"
android:id="@+id/ll"
android:layout_height="wrap_content">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tv"
    android:gravity="center"
    android:textSize="20sp"/>

</LinearLayout>

4) 結果:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM