TransWikia.com

Editar/Eliminar datos Firebase sobre un RecyclerView

Stack Overflow en español Asked by Cristian Prieto Beltran on January 19, 2021

Buenas, tengo una APP que muestra unos datos sobre Avisos (Nombre de aviso, descripcion, ubicacion) y todo esto esta guardado en FireBase, los datos los muestro con un RecyclerView y su Adaptador CardView.

Uso un PopupMenu para mostrar las 2 opciones
Como puedo hacer para hacer las opciones de Editar/Eliminar un Aviso??

Mi idea seria, saber en que posicion le das click del RecyclerView y que recojerr la Uid que tiene y editar sus datos, alguna idea de como podria hacerlo? Como saber la posicion y abrir el Aviso correcto?

Dejo por aqui el codigo que tengo para mostrar los Datos

public class VerAvisos extends MenuAvisos
{

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    FirebaseUser user = firebaseAuth.getInstance().getCurrentUser();

    List<Aviso> avisos;
    RecyclerView rv;
    AdaptadorAvisos adapter;

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

        avisos = new ArrayList<>();

        rv=(RecyclerView) findViewById(R.id.rvAvisos);
        rv.setLayoutManager(new LinearLayoutManager(this));
        adapter = new AdaptadorAvisos(this,avisos);
        rv.setAdapter(adapter);

        database.getReference("Aviso").child(user.getUid()).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                avisos.clear();
                for(DataSnapshot snapshot :
                        dataSnapshot.getChildren()){

                    Aviso aviso2 = snapshot.getValue(Aviso.class);
                    avisos.add(aviso2);

                }
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
}

Y su Adapter

public class AdaptadorAvisos extends RecyclerView.Adapter<AdaptadorAvisos.AvisosviewHolder> {

    List<Aviso> avisos;
    private Context mContext;

    public static class AvisosviewHolder extends RecyclerView.ViewHolder {

        TextView tvAviso;
        TextView tvDescripcion;
        TextView tvUbicacion;

        public AvisosviewHolder(View itemView) {
            super(itemView);
            tvAviso = (TextView) itemView.findViewById(R.id.tvAviso);
            tvDescripcion = (TextView) itemView.findViewById(R.id.tvDescripcion);
            tvUbicacion = (TextView) itemView.findViewById(R.id.tvUbicacion);
        }
    }

    public AdaptadorAvisos(Context mContext, List<Aviso> avisos)
    {
        this.mContext = mContext;
        this.avisos = avisos;
    }

    @Override
    public AvisosviewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_aviso, parent, false);
        AvisosviewHolder holder = new AvisosviewHolder(v);

        return holder;
    }

    @Override
    public void onBindViewHolder(final AvisosviewHolder holder, int position) {
        Aviso aviso = avisos.get(position);
        holder.tvAviso.setText(aviso.getAviso());
        holder.tvDescripcion.setText(aviso.getDescripcion());
        holder.tvUbicacion.setText(aviso.getUbicacion());

        holder.tvAviso.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPopupMenu(holder.tvAviso);
            }
        });
    }

    private void showPopupMenu(View v)
    {
        PopupMenu popup = new PopupMenu(mContext, v);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.menu_avisos, popup.getMenu());
        popup.setOnMenuItemClickListener(new MyMenuItemClickListener());
        popup.show();
    }

    class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener{

        public MyMenuItemClickListener(){
        }

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            Intent intent = null;
            switch (item.getItemId())
            {
                case R.id.action_eliminar:
                    Toast.makeText(mContext, "Eliminar Aviso (Test)", Toast.LENGTH_SHORT).show();
                    return true;
                case R.id.action_editar:
                    Toast.makeText(mContext, "Editar Aviso (Test)", Toast.LENGTH_SHORT).show();
                    return true;
                case R.id.action_volver:
                    intent = new Intent(mContext, Menu.class);
                default:
            }
            mContext.startActivity(intent);
            return true;
        }
    }

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

One Answer

Considero que sería más adecuado que el adapter pasara el aviso completo a la vista en el onClick por medio de un listener. Al final te paso un ejemplo. No obstante, también podrías enviarle el Aviso completo a la clase MyMenuItemClickListener y utilizarlo después en el onMenuItemClick

private void showPopupMenu(View v, Aviso aviso)
    {
        PopupMenu popup = new PopupMenu(mContext, v);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.menu_avisos, popup.getMenu());
        popup.setOnMenuItemClickListener(new MyMenuItemClickListener(aviso));
        popup.show();
    }
...
...
...
class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener{

private Aviso aviso;

public MyMenuItemClickListener(Aviso){
  this.aviso = aviso;
        }

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            Intent intent = null;
            switch (item.getItemId())
            {
                case R.id.action_eliminar:
                    Toast.makeText(mContext, "Eliminar Aviso (Test) " + aviso.getAviso(), Toast.LENGTH_SHORT).show();
                    return true;

...
...
...

Te paso un ejemplo de cómo puedes pasar Aviso a través de un nuevo listener. En el ejemplo, la entidad se llama Goal

Adapter

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

    private List<Goal> goalList;
    private GoalItemClickListener goalItemClickListener;

    public GoalListAdapter() {
    }

    public void setGoalList(List<Goal> goalList) {
        this.goalList = goalList;
        notifyDataSetChanged();
    }

    public void setGoalItemClickListener(GoalItemClickListener goalItemClickListener) {
        this.goalItemClickListener = goalItemClickListener;
    }

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

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Goal goal = goalList.get(position);
        holder.setClickListener(goal, goalItemClickListener);

        holder.tvTitle.setText(goal.getTitle());
        holder.tvDescription.setText(goal.getDescription());
    }

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

    public void add(Goal goal){
        if (!goalList.contains(goal)){
            goalList.add(goal);
            notifyDataSetChanged();
        }
    }

    public void update(Goal goal){
        if (goalList.contains(goal)){
            goalList.set(goalList.indexOf(goal), goal);
            notifyDataSetChanged();
        }
    }

    public void remove(Goal goal){
        if (goalList.contains(goal)){
            goalList.remove(goal);
            notifyDataSetChanged();
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.goal_list_item_tv_title)
        TextView tvTitle;
        @BindView(R.id.goal_list_item_tv_description)
        TextView tvDescription;

        private View view;

        public ViewHolder(View itemView) {
            super(itemView);
            this.view = itemView;
            ButterKnife.bind(this, view);
        }

        private void setClickListener(final Goal goal, final GoalItemClickListener listener){

            if (listener != null) {
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        listener.onItemClick(goal);
                    }
                });

                view.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        listener.onItemLongClick(goal);
                        return false;
                    }
                });
            }
        }
    }
}

Vista public class GoalListActivity extends BaseActivity implements GoalListView, GoalItemClickListener {

private static final String TAG = GoalListActivity.class.getSimpleName();

@BindView(R.id.goal_list_activity)
CoordinatorLayout coordinatorLayout;

@BindView(R.id.goal_list_activity_toolbar)
Toolbar toolbar;

@BindView(R.id.goal_list_activity_rv_concepts)
RecyclerView rvConcepts;

@Inject
GoalListPresenter presenter;

@Inject
GoalListAdapter adapter;

@Inject
LinearLayoutManager linearLayoutManager;

@Inject
VerticalDividerItemDecoration dividerItemDecoration;

@Override
protected int getToolbar() {
    return R.id.goal_list_activity_toolbar;
}

@Override
protected int getLayout() {
    return R.layout.goal_list_activity;
}

@Nullable
@Override
protected BasePresenter getPresenter() {
    return presenter;
}

@Override
public void setUpComponent(AppComponent appComponent) {
    DaggerGoalListComponent.builder()
            .appComponent(appComponent)
            .goalListModule(new GoalListModule(this))
            .build()
            .inject(this);
}

@Override
public void setUpView() {
    rvConcepts.setLayoutManager(linearLayoutManager);
    rvConcepts.addItemDecoration(dividerItemDecoration);
    rvConcepts.setHasFixedSize(true);
    rvConcepts.setAdapter(adapter);

    adapter.setGoalItemClickListener(this);
}

@Override
public void navigateToConceptAddView() {
    Intent intent = new Intent(this, GoalAddActivity.class);
    startActivity(intent);
}

@Override
public void showConceptList(List<Goal> goalList) {
    adapter.setGoalList(goalList);
}


@OnClick(R.id.goal_list_activity_fab)
public void onClick() {
    presenter.showConceptAdd();
}

@Override
public void showError(String message) {
    Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_LONG).show();
}

@Override
public void onItemClick(Goal goal) {

}

@Override
public void onItemLongClick(Goal goal) {

}

}

Como puedes observar, la vista setea el adapter en el recyclerview y setea la propia vista como GoalItemClickListener (adapter.setGoalItemClickListener(this);) ya que lo implementa

@Override
public void onItemClick(Goal goal) {

}

@Override
public void onItemLongClick(Goal goal) {

}

Answered by Pascual Montesinos on January 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP