I have TextView and Button in RecyclerView I put text on Button as number when I clicked the button I want that number increase by 1 when I try recursive setonclicklistener the application doesn't work
I have two activities each of them call the same adapter
the code of adapter
public class AzkaarAdapter extends RecyclerView.Adapter<AzkaarAdapter.AzkaarViewHolder> {
ArrayList<AzkarForm> azkarForms=new ArrayList<AzkarForm>();
Context ctx;
private static ItemClickCallback itemClickCallback;
public interface ItemClickCallback {
void onItemClick(int p);
void onSecondaryIconClick(int p);
}
public void setItemClickCallback(final ItemClickCallback itemClickCallback) {
this.itemClickCallback = itemClickCallback;
}
public AzkaarAdapter (ArrayList<AzkarForm> azkarForms,Context ctx){
this.azkarForms=azkarForms;
this.ctx=ctx;
}
#Override
public AzkaarViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
AzkaarViewHolder azkaarViewHolder;
if(ctx instanceof MainActivity){
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_layout,parent,false);
azkaarViewHolder=new AzkaarViewHolder(view,ctx,azkarForms);
}
else {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_details,parent,false);
azkaarViewHolder=new AzkaarViewHolder(view,ctx,azkarForms);
}
return azkaarViewHolder;
}
#Override
public void onBindViewHolder(AzkaarViewHolder holder, int position) {
AzkarForm azkarForm=azkarForms.get(position);
if(ctx instanceof MainActivity) {
holder.sample.setText(azkarForm.getComplete_morning());
holder.number.setText(String.valueOf(azkarForm.getNumber()));
}else {
holder.sample.setText(azkarForm.getComplete_morning());
holder.tally_count.setText(getTextNumber(azkarForm.getNumber()));
}
}
public String getTextNumber(int number){
String numberText="";
switch (number){
case 1:
numberText="مرة واحدة";
break;
case 3:
numberText="ثلاث مرات";
break;
case 4:
numberText="أربع مرات";
break;
case 7:
numberText="سبع مرات";
break;
case 10:
numberText="عشر مرات";
break;
case 100:
numberText="مائة مرة";
break;
}
return numberText;
}
#Override
public int getItemCount() {
return azkarForms.size();
}
public static class AzkaarViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView sample, number;
View container;
Context ctx;
ArrayList<AzkarForm> azkarForms = new ArrayList<AzkarForm>();
Button tally_count,press,next;
public AzkaarViewHolder(View itemView, Context ctx, ArrayList<AzkarForm> azkarForms) {
super(itemView);
this.ctx = ctx;
//itemView.setOnClickListener(this);
this.azkarForms = azkarForms;
if(this.ctx instanceof MainActivity) {
sample = (TextView) itemView.findViewById(R.id.sample);
number = (TextView) itemView.findViewById(R.id.number);
container = itemView.findViewById(R.id.container);
container.setOnClickListener(this);
}else {
sample = (TextView) itemView.findViewById(R.id.sample);
tally_count=(Button)itemView.findViewById(R.id.count);
press=(Button)itemView.findViewById(R.id.press);
press.setOnClickListener(this);
next=(Button)itemView.findViewById(R.id.next);
}
//container.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.container){
itemClickCallback.onItemClick(getAdapterPosition());
} else {
itemClickCallback.onSecondaryIconClick(getAdapterPosition());
}
/*if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP){
Pair<View, String> p1 = Pair.create((View)sample, "qoute");
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, p1);
}*/
}
}
}
First Activity
recyclerView =(RecyclerView) findViewById(R.id.recyclerviewcard);
layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter=new AzkaarAdapter(AzkaarData.getArrayListData(),this);
recyclerView.setAdapter(adapter);
adapter.setItemClickCallback(this);
toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public void onItemClick(int p) {
//int position=getAdapterPosition();
AzkarForm azkarForm= list.get(p);
Intent intent=new Intent(this,DetailsActivity.class);
intent.putExtra("numbers",azkarForm.getNumber());
intent.putExtra("sample",azkarForm.getSample());
intent.putExtra("complete",azkarForm.getComplete_morning());
intent.putExtra("position",p);
this.startActivity(intent);
}
#Override
public void onSecondaryIconClick(int p) {
}
Second Activity
recyclerView =(RecyclerView) findViewById(R.id.recyclerviewcard);
layoutManager=new LinearLayoutManager(DetailsActivity.this,LinearLayoutManager.HORIZONTAL,false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.scrollToPosition(pos);
adapter=new AzkaarAdapter(AzkaarData.getArrayListData(),this);
recyclerView.setAdapter(adapter);
SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public void onItemClick(int p) {
}
#Override
public void onSecondaryIconClick(int p) {
AzkarForm azkarForm= list.get(p);
press=(Button) findViewById(R.id.press);
int currentNum=Integer.parseInt(press.getText().toString());
int num=azkarForm.getNumber();
if(currentNum<num){
currentNum++;
onSecondaryIconClick(p);
}
press.setText(String.valueOf(currentNum));
}
Okay so, first off there is no need for your SecondaryIconClick callback, all because you want it to do something else doesn't mean you need two of them, you can just set the same ItemCallback interface for both activities and then call a switch statement to know which widget was clicked from the layouts. It's easier for me to show you with the code you have provided, I haven't tested any of this code.
From what I can see the First Activity, works fine (I assume this isn't causing the issues in question). Except for readability I would suggest initializing a global instance of the Context (private Context context = this) for that activity and then instead of new Intent(this, DetailsActivity.class) you should have new Intent(context, DetailsActivity.class) because sometimes 'this' can point to the ClickListener rather than the Activity.
For the Second Activity the logic for the counter and setText for the button seems fine except you have already initialized your Button in the ViewHolder, so you don't need to initialize it again in the click listener. All you have to do is pass the view to the listener. (see my edit for the Adapter and ViewHolder code) also, I don't know why you're calling a new instance of the click event if the currentNum < num.
Do you want the clicks to be automatic up until a certain number or just everytime they click up until a certain number?
Anyway, let's solve this problem for you. I'm writing this code with the assumption you want the counter to go up everytime the user clicks R.id.press.
FirstActivity
So as I suggest above change the context reference.
#Override
public void onItemClick(View v, int position) {
switch (v.getId()) {
case R.id.container:
AzkarForm azkarForm= list.get(position);
Intent intent=new Intent(context, DetailsActivity.class);
intent.putExtra("numbers",azkarForm.getNumber());
intent.putExtra("sample",azkarForm.getSample());
intent.putExtra("complete",azkarForm.getComplete_morning());
intent.putExtra("position", position);
context.startActivity(intent);
break;
}
SecondActivity
recyclerView =(RecyclerView) findViewById(R.id.recyclerviewcard);
layoutManager=new LinearLayoutManager(DetailsActivity.this,LinearLayoutManager.HORIZONTAL,false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.scrollToPosition(pos);
adapter=new AzkaarAdapter(AzkaarData.getArrayListData(),this);
recyclerView.setAdapter(adapter);
SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public void onItemClick(View v, int position) {
switch(v.getId()) {
case R.id.press:
AzkarForm azkarForm= list.get(position);
int currentNum=Integer.parseInt(press.getText().toString());
int num = azkarForm.getNumber();
if(currentNum < num){
currentNum++;
}
v.setText(String.valueOf(currentNum));
break;
}
RecyclerViewAdapter
Your new interface callbacks should be:
public interface ItemClickCallback {
void onItemClick(View v, int position);
}
public void setItemClickCallback(final ItemClickCallback itemClickCallback) {
this.itemClickCallback = itemClickCallback;
}
ViewHolder
Your new click listener should look like:
#Override
public void onClick(View v) {
if (itemClickCallback != null) {
itemClickCallback.onItemClick(v, getAdapterPosition());
/*if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP){
Pair<View, String> p1 = Pair.create((View)sample, "qoute");
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, p1);
}*/
}
}
}
Now you have a clean framework for your listeners and you're passing the correct views and calling the correct context, you're able to apply the logic accordingly without confusion between callbacks.
Hope this helps.
final Button counter = (Button) findViewById(R.id.counter_button);
counter.setText("1");
counter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int currNum = Integer.parseInt(counter.getText().toString());
counter.setText("" + currNum + 1);
}
});
Replace button id as per your layout.
Related
Listener in Android Studio RecyclerView custom adapter is returning null.
This is the Interface
private OnItemClickListener mlistener;
public interface OnItemClickListener{
void onItemClick(int position, Boolean paid);
}
public void setOnItemClickListener(OnItemClickListener listener){
mlistener = listener;
}
And this is the View Holder with the Listener. This is intended to pass a Boolean to the main activity.
public CartViewHolder(View itemView, ArrayList<Shift> shifts, OnItemClickListener listener) {
super(itemView);
paid = itemView.findViewById(R.id.due_back_paid);
containerView = itemView.findViewById(R.id.container);
paid.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position, isChecked);
}
}
}
});
containerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Shift current = (Shift)containerView.getTag();
Intent intent = new Intent(v.getContext(), ViewShiftActivity.class);
intent.putExtra("thisShift", current);
intent.putExtra("shifts", shifts);
v.getContext().startActivity(intent);
}
});
}
}
public LoadAdapter(ArrayList<Shift> shifts){
shiftList = shifts;
}
#NonNull
#Override
public CartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shift_row, parent, false);
CartViewHolder mvh = new CartViewHolder(view, shiftList, mlistener);
return mvh;
}
I have used this code in other projects and it works. I have can't seem to figure out what I am missing.
I've been asked to include the activity. The following is this code.
I have not added any code to the onItemClick here yet. waiting for the listener to work.
public class EditShiftActivity extends AppCompatActivity implements LoadAdapter.OnItemClickListener{
private ArrayList<Shift> shifts;
private RecyclerView lRecyclerView;
private LoadAdapter lAdapter;
private RecyclerView.LayoutManager lLayoutManager;
private View view;
private FloatingActionButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_shift);
Intent intent = getIntent();
shifts = intent.getParcelableArrayListExtra("shifts");
fab = findViewById(R.id.add_shift_edit);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(EditShiftActivity.this, AddShiftActivity.class);
intent1.putExtra("shifts", shifts);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
v.getContext().startActivity(intent1);
}
});
lRecyclerView = findViewById(R.id.shift_recycler);
lLayoutManager = new LinearLayoutManager(this);
lAdapter = new LoadAdapter(shifts);
lRecyclerView.setLayoutManager(lLayoutManager);
lRecyclerView.setAdapter(lAdapter);
}
#Override
public void onItemClick(int position, Boolean paid) {
}
}
Add below line in your code -
lAdapter = new LoadAdapter(shifts);
lAdapter.setOnItemClickListener(this);
You are retrieving the ArrayList<Shifts> from Intent. Check the size of shifts arraylist before sending to the Adapter. There is a chance that if the arraylist passed is empty then the adapter will return null and hence lRecyclerView will not be displayed.
Add this condition before passing data to adapter
//condition to check whether the arraylist is empty or not
if(!shifts.isEmpty()) {
lAdapter = new LoadAdapter(shifts);
//initialising the adapter
lRecyclerView.setAdapter(lAdapter);
}
My MainActivity has a recyclerview that will receive the products. In the floatActionButton of MainActivity and I call AddActivity which has the fields to add the product, including a recycler where I insert inputs to compose the price. the problem is exactly in the AddActivity recyclerView
I have a simple recyclerView and the adapter below where I do the CRUD before saving to the database, and everything works except the update, where I update the item through the adapter but the view in the list does not update the data. If you click on the same item to edit it again it shows the values that have already been updated and not those shown in the list.
Below my adapter:
public class InsumoAdapter extends RecyclerView.Adapter<InsumoAdapter.InsumoViewHolder>{
private final Context context;
private List<Insumo> insumos;
public InsumoAdapter(Context context, List<Insumo> insumos) {
this.context = context;
this.insumos = insumos;
}
#Override
public InsumoAdapter.InsumoViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.card_teste, viewGroup, false);
InsumoAdapter.InsumoViewHolder holder = new InsumoAdapter.InsumoViewHolder(view);
return holder;
}
public static class InsumoViewHolder extends RecyclerView.ViewHolder{
public TextView tNome, tVlrCusto;
ImageButton btnDelete;
CardView cardView;
public InsumoViewHolder(View view){
super(view);
tNome = (TextView) view.findViewById(R.id.txtNomeProd);
tVlrCusto = (TextView) view.findViewById(R.id.txtValorProd);
btnDelete = (ImageButton) view.findViewById(R.id.imgBtnDel);
cardView = (CardView) view.findViewById(R.id.cardProduto);
}
}
#Override
public void onBindViewHolder(final InsumoViewHolder holder, final int position) {
if(insumos.size() != 0){
final Insumo p = insumos.get(position);
holder.tNome.setText(p.getNomeInsumo());
holder.tVlrCusto.setText(p.getValor().toString());
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Clicou no Card para Editar na posição "+position,Toast.LENGTH_SHORT).show();
Bundle bundle = new Bundle();
//bundle.putString("nome", p.getNomeInsumo());
//bundle.putDouble("valor", p.getValor());
bundle.putInt("position", position);
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtras(bundle);
context.startActivity(intent);
//update(p, position);
}
});
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Clicou no Card para Excluir na posição "+position,Toast.LENGTH_SHORT).show();
delete(position);
}
});
}
}
#Override
public int getItemCount() {
return this.insumos != null ? this.insumos.size() : 0;
}
private void excluirInsumo(Context context, final int i){
String titulo = "Excluir";
String msg = "Deseja excluir este item?";
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle(titulo);
alertDialog.setMessage(msg);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Sim",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//deleta("Pproduto",produtos.get(i).get_id());
AddActivity addActivity = new AddActivity();
//addActivity.deleta(i);
dialog.dismiss();
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Não",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
private void delete(int position){
insumos.remove(position);
notifyItemRemoved(position);
}
public void update(Insumo insumo, int position){
insumos.set(position, insumo);
//notifyItemChanged(position);
notifyDataSetChanged();
}
public void insere(Insumo insumo){
insumos.add(insumo);
notifyDataSetChanged();
}
It's like not going back to onBindViewHolder to update the data. Could someone give me a light? If you need something, but you can't find any way.
Editing-----
AddActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
edtNome = (TextInputEditText) findViewById(R.id.edtNome);
valorCusto = (TextView) findViewById(R.id.txtValorCustoAdd);
valorVenda = (TextView) findViewById(R.id.txtValorVendaAdd);
valorPerc = (TextView) findViewById(R.id.txtValorPercAdd);
addItem = (FloatingActionButton) findViewById(R.id.fltBtnAddItem);
addFoto = (FloatingActionButton) findViewById(R.id.fltBtnAddFoto);
salvar = (FloatingActionButton) findViewById(R.id.fltBtnSalvar);
imgFoto = (ImageView) findViewById(R.id.imgFoto);
recyclerView = (RecyclerView) findViewById(R.id.recy);
edtNome.setTextIsSelectable(true);
valorCusto.setText(valor.toString());
valorPerc.setText("0");
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(true);
InsumoAdapter insumoAdapter = new InsumoAdapter(getApplicationContext(), insumos);
recyclerView.setAdapter(insumoAdapter);
insumoAdapter.notifyDataSetChanged();
addItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplication(), InsertActivity.class);
startActivity(intent);
}
});
salvar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Produto produto = new Produto();
produto.setpNome(edtNome.getText().toString());
produto.setpValorCusto(somaValor(insumos));
if(foto == 0){
produto.setPfoto(R.drawable.noimage);
}else{
produto.setPfoto(foto);
}
}
});
}
Activity of insumo's insert
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
insumo = new Insumo();
insumo.setNomeInsumo(nome.getText().toString());
Log.d(TAG, getClass()+" insumo.getNome = "+insumo.getNomeInsumo());
insumo.setValor(Double.parseDouble(valor.getText().toString()));
Log.d(TAG, getClass()+" insumo.getValor = "+insumo.getValor());
AddActivity addActivity = new AddActivity();
//addActivity.update(insumo, pos);
InsumoAdapter insumoAdapter = new InsumoAdapter(getBaseContext(), addActivity.lista());
insumoAdapter.update(insumo, pos);
insumoAdapter.notifyDataSetChanged();
finish();
}
});
MainAcitvity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerTeste);
FloatingActionButton btn = (FloatingActionButton) findViewById(R.id.fltBtnAdd);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(true);
ProdutoAdapter produtoAdapter = new ProdutoAdapter(getBaseContext(), produtos);
recyclerView.setAdapter(produtoAdapter);
produtoAdapter.notifyDataSetChanged();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
}
});
The problem is; you're creating a new instance of adapter instead of using the adapter attached to your recyclerView. Please use the same instance of adapter that's attached to your recyclerView.
In your Activity where your recyclerView is instantiated, use a member reference to contain your reference. i.e. mInsumoAdapter
Then when you create your first adapter instance and attach it to your recyclerView, assign it to mInsumoAdapter.
Finally use the same reference to call your update method.
mInsumoAdapter.update(insumo, pos);
For sharing references between activities and services, you can create a common sharing class like this:
public class ReferenceUtil {
private static InsumoAdapter insumoAdapter;
public static InsumoAdapter getMainAdapter(){
return insumoAdapter;
}
public static void setMainAdapter(InsumoAdapter adapter) {
insumoAdapter = adapter;
}
}
Then use ReferenceUtil.setMainAdapter(adapter); when you click on your FAB, and on your next activity use ReferenceUtil.getMainAdapter(); to obtain your attached reference and update that for your recyclerView to get updated on runtime.
Remember to set the static insumoAdapter in ReferenceUtil to null when you return back to your previous activity because it could lead to a memory leak in your application.
Instead of creating a new Adapter, just use the current adapter instance and use it for update and notifyDataSetChanged.
public InsumoAdapter insumoAdapter;
// Inside onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
....
insumoAdapter = new InsumoAdapter(getApplicationContext(), insumos);
....
}
// Inside Update onClick
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
....
insumoAdapter.update(insumo, pos)
insumoAdapter.notifyDataSetChanged()
}
Try with using notifyDataSetChnaged() in the activity from where you are passing the list to the adapter or you could do it after updating it. something like this,
RecyclerView.setAdapter(this,list);
notifyDataSetChanged();
or
InsumoAdapter.update(list,pos);
notifyDataSetChanged();
You could try use this way for all the CRUD operations.
I'm Using a RecyclerView that works well. Except that when I click on element 1 it returns element 3 when I scroll down. And when I scroll up and click on the element 4 it returns the element 3.
This is my adapter
public class StarRVAdapter extends RecyclerView.Adapter<StarRVViewHolder>{
private Context c;
private ArrayList<Questions> questionEntries;
Questions qe;
public StarRVAdapter(Context c, ArrayList<Questions> questionEntries,Questions qe) {
this.c = c;
this.qe = qe;
this.questionEntries = questionEntries;
}
#Override
public StarRVViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(c).inflate(R.layout.actu_list_item,parent,false);
return new StarRVViewHolder(v,c);
}
#Override
public void onBindViewHolder(StarRVViewHolder holder, int position) {
qe = (Questions)this.getItem(position);
holder.setDate(qe.getQuestion_date());
holder.setContent(qe.getQuestion_content());
holder.setImg(qe.getImgUrl());
holder.setTitle(qe.getQuestion_title());
holder.setAsker(qe.getQuestion_username());
holder.setIsRecyclable(true);
//this is My OnclickListener
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GoToView();
}
});
}
#Override
public int getItemCount() {
return questionEntries.size();
}
public Object getItem(int position) {
return questionEntries.get(position);
}
private void GoToView() {
Intent intent = new Intent(c,QuestionView.class);
Bundle b = new Bundle();
intent.putExtra("QuestionRef",qe.getTag_id());
intent.putExtra("ContentRef",qe.getQuestion_content());
intent.putExtra("TitleRef",qe.getQuestion_title());
intent.putExtra("ImgRef",qe.getImgUrl());
intent.putExtra("UsernameRef",qe.getQuestion_username());
intent.putExtra("DateRef",qe.getQuestion_date());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(c,intent, b);
//This is returning another item
}
}
Please help me
You are working with the wrong Questions object here. Allocate it in your click itself.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GoToView(holder.getAdapterPosition()); // passing position
}
});
Change the signature of GoToView accordingly:
private void GoToView(int position) {
Questions qe = (Questions)this.getItem(position);
// Cool stuff with qe
}
No need to keep it an instance variable
final Questions qe = (Questions)this.getItem(position);
holder.setDate(qe.getQuestion_date());
holder.setContent(qe.getQuestion_content());
holder.setImg(qe.getImgUrl());
holder.setTitle(qe.getQuestion_title());
holder.setAsker(qe.getQuestion_username());
holder.setIsRecyclable(true);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GoToView(qe);
}
});
and change your
private void GoToView(Questions qe) {
Intent intent = new Intent(c,QuestionView.class);
Bundle b = new Bundle();
intent.putExtra("QuestionRef",qe.getTag_id());
intent.putExtra("ContentRef",qe.getQuestion_content());
intent.putExtra("TitleRef",qe.getQuestion_title());
intent.putExtra("ImgRef",qe.getImgUrl());
intent.putExtra("UsernameRef",qe.getQuestion_username());
intent.putExtra("DateRef",qe.getQuestion_date());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(c,intent, b);
//This is returning another item
}
What I'm trying to do is to pass a data from a specific user into another activity using it's userID as unique ID
It keeps send the same data into the other activity, I dont know how to do it
This is code is for the Fragment_Home where I use to get data from Firebase and populate it into the RecyclerView, and where the Onclick is in at the moment.
public class FragmentRO_Home extends Fragment {
private Intent intent;
private DatabaseReference database;
RecyclerView recyclerView;
Recycler_View_Adapter adapter;
TextView TV_nodata;
private String uid;
private String nombre;
public FragmentRO_Home() {
// Required empty public constructor qwe
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_ro__home,container,false);
database = FirebaseDatabase.getInstance().getReference();
final List<Data> data = new ArrayList();
TV_nodata = (TextView)view.findViewById(R.id.TV_result);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
adapter = new Recycler_View_Adapter(data, getActivity());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
fill_with_data();
This is the onclick which I'm using with recyclerview and it's functionable.
recyclerView.addOnItemTouchListener(new CustomRVItemTouchListener(getActivity(), recyclerView, new RecyclerViewItemClickListener() {
#Override
public void onClick(View view, int position) {
if (position == 0){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 1){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 2){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 3){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 5){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
This is the method to where I populated my recyclerview from getting data's in the firebase.
public void fill_with_data() {
database.child("data_home").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot d) {
if (d.exists()) {
List<Data> list = new ArrayList<>();
for (DataSnapshot dataw : d.getChildren()) {
Data data = dataw.getValue(Data.class);
list.add(data);
uid = (data.usirayd);
nombre = (data.title);
}
for (Data data : list) {
adapter.insert(new Data(data.title, data.description, data.condition, data.time,data.usirayd));
}
}else {
TV_nodata.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
recyclerView.setAdapter(adapter);
}
Try this code
recyclerView.addOnItemTouchListener(new CustomRVItemTouchListener(getActivity(), recyclerView, new RecyclerViewItemClickListener() {
#Override
public void onClick(View view, int position) {
if(data.size()>position){
if (data.get(position)!= null){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",data.get(position).usirayd);
startActivity(intent);
}
}
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
Your list is of Data type so what you need to do is make Data class parcleable and then get object form the clicked position and send it to activity.
Sample code is something like this
public void onClick(View view, int position) {
Data dataObject = list.get(position);
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
intent.putExtra("Data",dataObject);
startActivity(intent);
}
If you want to send single id of clicked position then just get Id from list object and send like this
uid= list.get(postion).getUserId;
and send it in intent
and in other class/activity receice that parcelable object like this
Data dataObjectReceived = getIntent().getExtras().getParcelable("Data");
and if you want to get single entity then get it by its key
When clicking on the cardView you want to pass the data into your activity or fragment for that you need to make one interface for example in my case may use one FriendModel
Interface
public interface OnFriendListClickListener {
void onItemClick(FriendModel model, int position);
}
Activity
public class FriendListActivity extends AppCompactActivity
implements
OnFriendListClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_friend);
//...
rvRemoveFriendList.setAdapter(new FriendListAdapter(context, list, this));
}
#Override
public void onItemClick(FriendModel model, int position) {
//your code here
}
}
Adapter
public class FriendListAdapter extends RecyclerView.Adapter<FriendListAdapter.FriendListHolder> {
private List<FriendModel> friendList;
private Context context;
private OnFriendListClickListener listener;
public FriendListAdapter(Context context,
List<FriendModel> friendList,
OnFriendListClickListener listener,) {
this.context = context;
this.friendList = friendList;
this.listener = listener;
}
#Override
public FriendListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new FriendListHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_friend, parent, false));
}
#Override
public void onBindViewHolder(final FriendListHolder holder, int position) {
holder.tvFriendNumber.setText(friendList.get(position).getFriendMobile());
holder.llFriendListItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onItemClick(friendList.get(holder.getAdapterPosition()),
holder.getAdapterPosition());
}
});
}
//......
}
I have a RecyclerView which contains multiple item types (4 or 5 at least).
Some items can be clicked, sometimes they have two differents clickListener (for example two imageView in one item).
For now, the item manages the clicks himself like this :
item.imageView1.setOnClickListener(....){
startActivity(Activity2);
}
item.imageView2.setOnClickListener(....){
startActivity(Activity1);
}
But I have a problem : I need to put some variables in the activity which will be started, so what is the best way to do this :
1) My item need to know these variables and continues to manage his own click ?
2) My item has a listener which call startActivity with the variables (like the fragment or parent activity or an object dedicated to this) ?
If you need more precisions, ask me.
Thx.
Make an interface for passing those values.
public interface MyRecyclerCallback {
void onItemClicked(Integer o); //insert whatever you want to pass further, possibly translated to form packable to intents
}
Then add it to your adapter from the activity with recycler like you would any listener. Either constructor or by separate method.
Pass it further down to every children upon their creation.
Call it when onClick gets detected with appropriate argument.
The actual argument may be some abstract thing
depending on your logic. It's more of a general idea. That's the way I do it with my recyclers.
In your activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecycler = (RecyclerView) findViewById(R.id.recycler);
MyAdapter adapter = new MyAdapter(this,new MyRecyclerCallback() {
#Override
public void onItemClicked(Integer o) { //any argument you like, might be an abstract
Intent i = new Intent(this,ActivityTwo.class);
i.putExtra(EXTRA_VALUE,o);
startActivity(i);
}
});
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(adapter);
}
Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Child>{
private final Context mContext;
private final MyRecyclerCallback mCallback;
private List<Integer> mChildren;
public MyAdapter(Context ctx, MyRecyclerCallback myRecyclerCallback) {
mContext = ctx;
mCallback = myRecyclerCallback;
mChildren = new ArrayList<>();
}
public void populateList(List<Integer> list ) { //this can be a network call or whatever you like
mChildren.addAll(list);
}
#Override
public Child onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
return new Child(v,mCallback);
}
#Override
public void onBindViewHolder(Child holder, int position) {
holder.setValue1(mChildren.get(position)*3);
holder.setValue2(mChildren.get(position));
}
#Override
public int getItemCount() {
return mChildren.size();
}
public class Child extends RecyclerView.ViewHolder{
View mView1;
View mView2;
private int mValue1;
private int mValue2;
public Child(View itemView, final MyRecyclerCallback mCallback) {
super(itemView);
mView1 = itemView.findViewById(R.id.view1);
mView2 = itemView.findViewById(R.id.view2);
mView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onItemClicked(mValue1);
}
});
mView2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onItemClicked(mValue2);
}
});
}
public void setValue1(int position) {
mValue1 = position;
}
public void setValue2(int position) {
mValue2=position;
}
}
}
this a good alternative to handle onclick and onlongclick
ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/
You can have a single OnClickListener on your ViewHolder class and use it with an interface to determine the type of item which has been clicked.
For example, say you have a model class called Item :
public class Item {
private int itemType;
private String itemDescription;
private String optionalExtra;
public static final int ITEM_TYPE_1 = 1;
public static final int ITEM_TYPE_2 = 2;
public Item(int itemType, String itemDescription) {
this.itemType = itemType;
this.itemDescription = itemDescription;
}
public Item(int itemType, String itemDescription, String optionalExtra) {
this.itemType = itemType;
this.itemDescription = itemDescription;
this.optionalExtra = optionalExtra;
}
}
You have a custom interface defined to intercept click on items in recyclerview :
public interface CustomClickListener {
void onClickOfItemType1( int position );
void onClickOfItemType2( int position );
}
Inside your adapter for recyclerview, in the viewholder class :
//Similar implementation for other ViewHolders too.
public class ViewHolderType1 extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView imageView;
TextView textView;
View itemView;
public ViewHolderType1(View view) {
super(view);
this.itemView = view;
//initialize other views here
//Set item click listener on your view
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int itemPosition = getAdapterPosition();
if( itemPosition != RecyclerView.NO_POSITION ) {
customClickListener.onClickOfItemType1(itemPosition);
//You can call onClickOfItemType2(itemPosition) in your other type of view holder class
}
}
}
In your Activity or Fragment :
Pass the customClickListener as a parameter to your adapeter :
CustomAdapter customAdapter = new CustomAdapter(List<Item> itemList, new CustomClickListener {
#Override
void onClickOfItemType1(int position) {
Item item = itemList.get(position);
//This item is of type 1
//You can implement serializable / parcelable in your item class and use it to directly pass across item to your activity
Intent intent = new Intent(Activity.this, CustomActivity1.class);
intent.putExtra("item", item);
startActivity(intent);
}
#Override
void onClickOfItemType2(int position) {
Item item = itemList.get(position);
//This item is of type 2
//You can implement serializable / parcelable in your item class and use it to directly pass across item to your activity
Intent intent = new Intent(Activity.this, CustomActivity2.class);
intent.putExtra("item", item);
startActivity(intent);
}
});
In case you are trying to trigger different activities on click of different views; inside your viewclicklistener implementation check the view id and trigger the corresponding activity.
#Override
public void onClick(View v) {
int itemPosition = getAdapterPosition();
if( itemPosition != RecyclerView.NO_POSITION ) {
switch(v.getId()) {
case R.id.imageView :
customClickListener.onClickOfItemType1(itemPosition);
break;
case R.id.textView :
customClickListener.onClickOfItemType2(itemPosition);
break;
}
}
}
This is a guide for usage of RecyclerView :
https://guides.codepath.com/android/using-the-recyclerview