简体   繁体   中英

Android: removing recycler view through fragment

Question:

I'm adding views into a recyclerview with a click. When I click a view it opens a DialogFragment, how do I remove that view through the DialogFragment (by clickign on a button inside it)?

Adapter:

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

    public List<String> items = new ArrayList<>();
    public Activity mcontext;

    public SubjectsAdapter(Activity context) {
        this.mcontext=context;

    }

    public void addItem(String name) {
        items.add(name);
        notifyItemInserted(items.size() - 1);
    }

    public void removeItem(int position) {
        items.remove(position);
        notifyItemRemoved(position);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.grid_item_button, parent, false);
        view.requestFocus();
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.setButtonName(items.get(position));
    }

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


    int i = 100;
    public EditText EditName;

    class ViewHolder extends RecyclerView.ViewHolder{

        public Button GridButton;
        public SharedPreferences prefs;

        public ViewHolder(View itemView) {
            super(itemView);

            GridButton = (Button) itemView.findViewById(R.id.grid_button);
            EditName = (EditText) itemView.findViewById(R.id.editName);
            ClassName = (TextView) itemView.findViewById(R.id.ClassName);
            prefs = mcontext.getPreferences(Context.MODE_PRIVATE);

            GridButton.setId(++i);

            EditName.requestFocus();

            //Showing the DialogFragment
            GridButton.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Fragment_Subject_Edit editFragment = Fragment_Subject_Edit.newInstance();

                    Bundle data = new Bundle();
                    data.putInt("ID", v.getId());
                    editFragment.setArguments(data);

                    editFragment.show(mcontext.getFragmentManager(), "Title");
                    return false;
                }
            });
        }

        public void setButtonName(String buttonName) {
            GridButton.setText(buttonName);
        }
    }
}

Adding views in the activity:

    recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
    final SubjectsAdapter adapter = new SubjectsAdapter(this);
    recyclerView.addItemDecoration(new SampleItemDecoration());
    recyclerView.setAdapter(adapter);
    recyclerView.setItemViewCacheSize(15);
    recyclerView.setNestedScrollingEnabled(false);


 @Override
 public void onClick(View v) {           

       adapter.addItem(prefs.getString("key1", null));

  }

What I have from Lucas Crawford answer, although I'm not getting it right:

1:

public Activity mcontext;
public View.OnLongClickListener LongClicking;

public SubjectsAdapter(Activity context, View.OnLongClickListener longClick) {
    this.mcontext = context;
    this.LongClicking = longClick;
}

2:

View.OnLongClickListener LongClicker;
...
...
...
        adapter = new SubjectsAdapter(this, LongClicker);
        recyclerView.setAdapter(adapter);

3:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.grid_item_button, parent, false);
    view.setOnLongClickListener(LongClicking);
    return new ViewHolder(view);
}

4:

        fm = getFragmentManager();
        ClassEditor = new Fragment_Subject_Edit();

        LongClicker = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            Bundle data = new Bundle();
            data.putInt("ID", v.getId());
            ClassEditor.setArguments(data);
            ClassEditor.show(fm, "Title");
            return false;
        }
    };

Nothing happens when I longClick the button, nor anywhere in the view, what's wrong with these steps, and how to do number 5?

Easy Solution

Instead of assigning the onLongClickListener in the ViewHolder, I would assign the click listener as part of the constructor in the adapter's creation. This way, when you create the view holder in onCreateViewHolder, you give the new view for the view holder the adapter's passed click listener. This is better since it decouples the click event from the ViewHolder's work, as well as letting the activity that created the adapter handle what happens when clicked. (also the dialog fragment created is tied to an Activity lifecycle, why not create it there!).

Next, add a click listener to the dialog fragment's creation, possible as a member variable with a getter/setter. The button in the fragment is then assigned that click listener when you are inflating the dialog fragments view. This way, you do all the click event listening within your Activity, and use the same strategy in both the adapter and dialog fragment.

Can provide code IF required. I hope that makes sense.

Here is a list of what I suggested:

  1. Add a click listener to the constructor of the recycler view adapter.
  2. Pass an onLongClickListener object when you are creating the adapter within your activity.
  3. Assign your view the click listener passed to the adapter in onCreateViewHolder.
  4. Within the click listener created in your activity for the adapter, create the dialog fragment and assign a NEW click listener to handle the button press you desire. This click listener also is apart of the Activity.
  5. When inflating the views in the dialog fragment, give the target button the listener you assigned to the dialog fragment.

The logic of removing the view (or item) from the RecyclerView adapter would be in the click listener you assign to the new dialog fragment. You need a reference to the item currently being removed as well (which you do via arguments).

Advanced Solution

A more advanced solution would be to use something like EventBus which handles listening for events. It cleans up a lot of code to use this. Another one is Otto by Square. It does the same thing, and I personally use Otto for event driven listening rather than passing around click listeners. You can decouple the need for a click listener being passed to your recycler's adapter by just setting a click listener in the adapter that posts an event that your activity is listening for, which then triggers the dialog fragment creation. The dialog fragment would then do the same thing by creating and assigning a new listener within the fragment that posts another event that your activity is listening for related to removing the particular adapter item.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM