linear layout click not working, what am i doing wrong? [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
i have a view that i want to set it clickable to open a new activity. the code runs without any errors but when i click on a list in the main activity, nothing happens. the list displays alright but when a particular data is clicked, nothing at all happens. this is the code for the adapter
package com.example.helpresponse;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Locale;
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
ArrayList<AndroidTargets> targetsArrayList;
private Context context;
private HandleClick mHandleClick;
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData) {
targetsArrayList = mTargetData;
}
public void setmHandleClick(HandleClick handleClick) {
this.mHandleClick = handleClick;
}
#NonNull
#Override
public TargetViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
context = viewGroup.getContext();
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
/*
viewHolder.myClickableView.setOnClickListener((v) -> {
Intent intent = new Intent(context, MapsActivity.class);
//int myData = 1;
//intent.putExtra("myDataKey", myData);
//more intent.putExtra(s) as needed
context.startActivity(intent);
});
*/
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do your stuff
Intent intent = new Intent(context, MapsActivity.class);
int myData = 1;
intent.putExtra("myDataKey", myData);
//more intent.putExtra(s) as needed
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
if(targetsArrayList == null)
return 0;
return targetsArrayList.size();
}
public class TargetViewHolder extends RecyclerView.ViewHolder {
protected TextView androidTargetName;
protected TextView androidTargetNumber;
protected TextView androidTargetShortName;
protected LinearLayout myClickableView;
public TargetViewHolder(#NonNull View itemView) {
super(itemView);
myClickableView = itemView.findViewById(R.id.linearLayout);
androidTargetShortName = itemView.findViewById(R.id.textView2);
androidTargetName = itemView.findViewById(R.id.textView3);
androidTargetNumber = itemView.findViewById(R.id.textView4);
}
}
public interface HandleClick {
void onItemClick(int index);
}
}
this code is the main activity
package com.example.helpresponse;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class ShowStudentDetailsActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
RecyclerView.Adapter adapter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ShowStudentDetailsActivity.this));
progressDialog = new ProgressDialog(ShowStudentDetailsActivity.this);
progressDialog.setMessage("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new RecyclerViewAdapter(ShowStudentDetailsActivity.this, list);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
}
this code is the layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
>
<TextView
android:id="#+id/textView2"
android:textColor="#color/colorPrimary"
style="#style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="textview"
android:minWidth="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"/>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textView2"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"
>
<TextView
android:id="#+id/textView3"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginBottom="8dp"
android:text="textview"
android:clickable="true"/>
<TextView
android:layout_marginTop="8dp"
android:id="#+id/textView4"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="textview"
android:clickable="true"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
please help, thank you

You are not using your implementation, this should solve your problem.
public class ShowStudentDetailsActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
TargetDataAdapter adapter;
...
adapter = new TargetDataAdapter(list);

The problem is with you interface with you even you are not using in MainActivity.
Ex how to implement interface.
Step : 1 create interface in adapter :
public interface IHomeSelector{
void onCategorySelected(int postion);
}
Step : 2 In ViewHolder use interface
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView category;
private ImageView category_icon;
private IHomeSelector iHomeSelector;
public ViewHolder(#NonNull View itemView, IHomeSelector iHomeSelector) {
super(itemView);
category = itemView.findViewById(R.id.category_title);
category_icon = itemView.findViewById(R.id.category_icon);
this.iHomeSelector = iHomeSelector;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
iHomeSelector.onCategorySelected(getAdapterPosition());
}
}
Step :3 Pass interface in adapter constructor
public class HomeRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<String> mCategories = new ArrayList<>();
private Context mContext;
private IHomeSelector mIHomeSelector;
public HomeRecyclerAdapter(ArrayList<String> mCategories, Context mContext, IHomeSelector mIHomeSelector) {
this.mCategories = mCategories;
this.mContext = mContext;
this.mIHomeSelector = mIHomeSelector;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_category_list_item, null);
return new ViewHolder(view, mIHomeSelector);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
((ViewHolder)viewHolder).category.setText(mCategories.get(i));
RequestOptions requestOptions = new RequestOptions()
.error(R.drawable.ic_launcher_background);
Drawable iconResource = null;
switch(mCategories.get(i)){
case "Music":{
iconResource = ContextCompat.getDrawable(mContext, R.drawable.ic_audiotrack_white_24dp);
break;
}
case "Podcasts":{
iconResource = ContextCompat.getDrawable(mContext, R.drawable.ic_mic_white_24dp);
break;
}
}
Glide.with(mContext)
.setDefaultRequestOptions(requestOptions)
.load(iconResource)
.into(((ViewHolder)viewHolder).category_icon);
}
#Override
public int getItemCount() {
return mCategories.size();
}
Last step implement interface in activity :
public class HomeFragment extends Fragment implements HomeRecyclerAdapter.IHomeSelector
{
private static final String TAG = "HomeFragment";
// UI Components
private RecyclerView mRecyclerView;
// Vars
private HomeRecyclerAdapter mAdapter;
private ArrayList<String> mCategories = new ArrayList<>();
private IMainActivity mIMainActivity;
public static HomeFragment newInstance(){
return new HomeFragment();
}
#Override
public void onHiddenChanged(boolean hidden) {
if(!hidden){
mIMainActivity.setActionBarTitle(getString(R.string.categories));
}
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
initRecyclerView(view);
mIMainActivity.setActionBarTitle(getString(R.string.categories));
}
private void initRecyclerView(View view){
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mAdapter = new HomeRecyclerAdapter(mCategories, getActivity(), this); // passing 3 rd parameter this for interface
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onCategorySelected(int postion) {
Log.d(TAG, "onCategorySelected: list item is clicked!");
//Here implement you code not in adapter
}
}
Just follow this step if still stuck let me know.Happy Coding!!!

First you created a custom adapter and did not use it.
secondly you're trying to reduce the work load of the adapter by abstracting some of it functionality like onClickListeners, yet you still perform the onClick inside the adapter which almost defeat the purpose of the abstraction.
Finally, interfaces are basically to be implemented and I'm curious on how you missed that.
Below is a commented and correct snippet of your code, you will understand it better if and only if you read the comments.
First your adapter:
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
ArrayList<AndroidTargets> targetsArrayList;
private Context context;
private HandleClick mHandleClick;
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData) {
targetsArrayList = mTargetData;
}
public void setmHandleClick(HandleClick handleClick) {
this.mHandleClick = handleClick;
}
#NonNull
#Override
public TargetViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
context = viewGroup.getContext();
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do your stuff
mHandleClick.onItemClick(i);//here is where you call the onItemClick method in the interface
}
});
}
public interface HandleClick {
void onItemClick(int index);
}
}
Your ShowStudentDetailsActivity:
//Take note of the implements keyword
public class ShowStudentDetailsActivity extends AppCompatActivity, implements HandleClick {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
ArrayList<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
TargetDataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ShowStudentDetailsActivity.this));
progressDialog = new ProgressDialog(ShowStudentDetailsActivity.this);
progressDialog.setMessage("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new TargetDataAdapter(list);
/*The this keyword below parses whatever setmHandleClick() method needs that's present in that same class, which is the onItemClick() method in the interface that we implemented. So, the this keyword simply is a reference to ShowStudentDetailsActivity as an object, including all it resources like context */
adapter.setmHandleClick(this)
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
/* This is the result of the implemented interface above using implements keyword
you will note that without the below method, our class will show error and it's
basically telling us to do like below. So, when you implement an interface, you will be forced to have all its method implemented like below also.
I will suggest you read more on interface in java.*/
#Override
void onItemClick(int index){
//note that we have moved the code that was in the adapter back to the activity it self.
Intent intent = new Intent(this, MapsActivity.class);
int myData = index;
intent.putExtra("myDataKey", myData);
startActivity(intent);
}
}
That's it.
Bonus, below is a little bit more better approach and readable version.
Firstly I will put my interface in a separate file.
public interface HandleClick {
void onItemClick(int index);
}
Secondly my adapter:
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
private ArrayList<AndroidTargets> targetsArrayList;
private HandleClick mHandleClick;
/*Note that the constructor now take two params which helps us get ride of setmHandleClick() method.*/
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData, HandleClick handleClick) {
targetsArrayList = mTargetData;
mHandleClick = handleClick;
}
#NonNull
#Override
public TargetViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
/* There is an interesting way to make below code neater by abstracting it back to the Activity incharge, let me know if you want that...priority now is to focus on fixing your issue. */
#Override
public void onBindViewHolder(#NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mHandleClick.onItemClick(i);
}
});
}
}
My ShowStudentDetailsActivity:
//Note that you can implement more than one interfaces, that's one of it's beauty.
public class ShowStudentDetailsActivity extends AppCompatActivity, implements HandleClick {
private DatabaseReference databaseReference;
ProgressDialog progressDialog;
private ArrayList<StudentDetails> list = new ArrayList<>();
private RecyclerView recyclerView;
private TargetDataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
initRecyclerView();
initProgressDialog("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new TargetDataAdapter(list, this);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
private void initProgressDialog(String msg){
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(msg);
}
private void initRecyclerView(){
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
/*LinearLayoutManager.VERTICAL is to set the orientation of my list items in the recyclerView, and the boolean value When set to true, layouts from end to start, otherwise start to end.*/
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
}
#Override
void onItemClick(int index){
Intent intent = new Intent(this, MapsActivity.class);
int myData = index;
intent.putExtra("myDataKey", myData);
startActivity(intent);
}
}

Related

(mainActifity)fragment --> new fragment passing object from list using an interface

I have trouble with 2 things.
Somehow I cannot make my interface onClickListener work.
After I got the first problem solved, I have not an idea about how to start fragmentB to display the book (fragmentA has a RecycleView with books)
Did I check and tried solutions on stack/google?
Yes, I did, have been struggling with these problems for the last 2 days.
Some codes are old, some I cannot figure out how to implement it in my code, as I am still a beginner.
FragmentA(mangasSearch) is part of MainActivity (not sure if you want to see the code of MainActivity)
FragmentB will be a new Fragment that when pressed back, will be destroyed and get back to fragmentA
Here is my RecycleView
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import Classes.Manga;
public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
private ArrayList<Manga> mDataSet;
private Context context;
public MyAdapterRecyclerView(ArrayList<Manga> dataSet, Context context) {
mDataSet = dataSet;
this.context = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleview_item, parent, false);
// final RecyclerView.ViewHolder holder = new MyViewHolder(view);
return new MyViewHolder(view);//, communicator);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Picasso.get().load(mDataSet.get(position).getPosterPicture()).into(holder.imageviewBookCover);
holder.tvBookTitle.setText("This is book nr: " + position + " and title " + mDataSet.get(position).getTitle());
}
#Override
public int getItemCount() {
return mDataSet.size();
}
private static OnMangaBookClickListener onMangaBookClickListener;
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imageviewBookCover;
public TextView tvBookTitle;
OnMangaBookClickListener onMangaBookClickListener;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
imageviewBookCover = itemView.findViewById(R.id.imageView_bookcover);
tvBookTitle = itemView.findViewById(R.id.textView_booktitle);
itemView.setOnClickListener((View.OnClickListener) onMangaBookClickListener);
}
#Override
public void onClick(View view) {
onMangaBookClickListener.onMangaBookClick(getAdapterPosition(), view);
}
}
public void setOnMangaBookClickListener(OnMangaBookClickListener onMangaBookClickListener) {
MyAdapterRecyclerView.onMangaBookClickListener = onMangaBookClickListener;
}
public interface OnMangaBookClickListener {
void onMangaBookClick(int position, View view);
}
}
Here I made the interface, so I call it on fragmentA and create FragmentB.
Here is fragmentA code
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import Classes.JsonHandling;
import Classes.Manga;
public class MangasSearchFragment extends Fragment {
private RecyclerView recyclerView;
private MyAdapterRecyclerView mAdapter;
private RecyclerView.LayoutManager layoutManager;
private Bundle results;
private ArrayList<Manga> mangaTempList;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mangas_to_search, container, false);
Context context = getActivity();
recyclerView = view.findViewById(R.id.recyclerview_manga_book);
mangaTempList = new JsonHandling(context).getMangaBookJson();
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(new GridLayoutManager(context, 3));
// specify an adapter (see also next example)
mAdapter = new MyAdapterRecyclerView(mangaTempList, context);
mAdapter.setOnMangaBookClickListener(new MyAdapterRecyclerView.OnMangaBookClickListener() {
#Override
public void onMangaBookClick(int position, View view) {
Toast.makeText(getContext(), "WHAT?!", Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(mAdapter);
return view;
}
}
OK for onClickListener you create an Interface in your adapter and make the Fragment implements it and pass it to the adapter constructor f.e
public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
......
OnItemInteractListener mListner;
public MyAdapterRecyclerView(ArrayList<Manga> dataSet, OnItemInteractListener listener){
this.mListner = listener;
......
// your adapter code
public interface OnItemInteractListener{
void onItemInteract(int position);
}
}
and in your fragment
public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnItemInteractListener{
// this will automatically ask you to override the onItemIteract method where you'll display your toast or open your fragment
....
// your fragment code
mAdapter = new MyAdapterRecyclerView(mangaTempList, this); // pass the listener to adapter using this
this is basically how you communicate between adapter and fragment
you use that mListener variable in adapter whenever the user clicks on an item
and the easy way to listen to user click is inside onBindViewHolder method
using
viewHolder.YourView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.onItemInteract(position);
}
}
so the final code of yours should be like this
MyAdapterRecyclerView
public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
private ArrayList<Manga> mDataSet;
private Context context;
OnMangaBookClickListener mListener;
public MyAdapterRecyclerView(ArrayList<Manga> dataSet, OnMangaBookClickListener listener) {
mDataSet = dataSet;
this.mListener = listener;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleview_item, parent, false);
// final RecyclerView.ViewHolder holder = new MyViewHolder(view);
this.context = parent.getContext();
return new MyViewHolder(view);//, communicator);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, final int position) {
Picasso.get().load(mDataSet.get(position).getPosterPicture()).into(holder.imageviewBookCover);
holder.tvBookTitle.setText("This is book nr: " + position + " and title " + mDataSet.get(position).getTitle());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.onMangaBookClick(position);
}
});
}
#Override
public int getItemCount() {
return mDataSet.size();
}
private static OnMangaBookClickListener onMangaBookClickListener;
public static class MyViewHolder extends RecyclerView.ViewHolder {
public ImageView imageviewBookCover;
public TextView tvBookTitle;
public View itemView;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
this.itemView = itemView;
imageviewBookCover = itemView.findViewById(R.id.imageView_bookcover);
tvBookTitle = itemView.findViewById(R.id.textView_booktitle);
}
}
public interface OnMangaBookClickListener {
void onMangaBookClick(int position);
}
}
and for MangasSearchFragment
public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnMangaBookClickListener{
private RecyclerView recyclerView;
private MyAdapterRecyclerView mAdapter;
private RecyclerView.LayoutManager layoutManager;
private Bundle results;
private ArrayList<Manga> mangaTempList;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mangas_to_search, container, false);
Context context = getActivity();
recyclerView = view.findViewById(R.id.recyclerview_manga_book);
mangaTempList = new JsonHandling(context).getMangaBookJson();
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(new GridLayoutManager(context, 3));
// specify an adapter (see also next example)
mAdapter = new MyAdapterRecyclerView(mangaTempList, this);
recyclerView.setAdapter(mAdapter);
return view;
}
#Override
public void onMangaBookClick(int position) {
Toast.makeText(getContext(), "item "+position,
Toast.LENGTH_SHORT).show();
}}
Edit
That's for second part use that code where you're using Toast
in FragmentA use this inside the onClickLisnter and pass the position ( or any data using bundle )
public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnMangaBookClickListener{
private RecyclerView recyclerView;
private MyAdapterRecyclerView mAdapter;
private RecyclerView.LayoutManager layoutManager;
private Bundle results;
private ArrayList<Manga> mangaTempList;
int containerID = 0;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
containerID = container.getId();
... // your code
}
#Override
public void onMangaBookClick(int position) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
FragmentB fragmentB = new FragmentB();
fragmentB.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction()
.replace(containerID, fragmentB, "FragmentB")
.addToBackStack(null)
.commit();
}}
and use getArguments() in FragmentB to retrieve the data
int position = getArguments().getInt("position");
add this to Fragment

I want to make a swipeable activity

I'm working on an Android project and I want to make a swipeable activity that has a textview in it so When the user swipes the textview value changes!
I want to make the SingleItem class swipeable so that the user can see more content about the book when they swipe.
Here is my code!!!
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
List<Book> books;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
books = new ArrayList<>();
books.add(new Book("Rich Dad Poor Dad", "Rich Dad Poor Dad is a 1997 book written by Robert Kiyosaki and Sharon Lechter.", "Robert Kiyosaki"));
books.add(new Book("Awaken The Giant Within", "Wake up and take control of your life! From the bestselling author of Inner Strength, Unlimited Power, and MONEY Master the Game", "Anthony Robbins"));
mRecyclerView = findViewById(R.id.my_recyclerview);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new RecyclerViewAdapter(books, this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
}
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<Book> bookList;
private Context mContext;
public RecyclerViewAdapter(List<Book> bookList, Context mContext) {
this.bookList = bookList;
this.mContext = mContext;
}
#NonNull
#Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view ;
LayoutInflater mInflater = LayoutInflater.from(mContext);
view = mInflater.inflate(R.layout.item_list,viewGroup,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewAdapter.ViewHolder viewHolder, final int i) {
viewHolder.bookTitle.setText(bookList.get(i).getmTitle());
viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, SingleItem.class);
intent.putExtra("Description", bookList.get(i).getmDescription());
intent.putExtra("Author", bookList.get(i).getmAuthor());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return bookList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public View view;
public TextView bookTitle;
public CardView cardView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
bookTitle = itemView.findViewById(R.id.book_title);
cardView = itemView.findViewById(R.id.my_card_view);
view = itemView;
}
}
SingleItem.java
public class SingleItem extends AppCompatActivity {
private TextView bookDescription, bookAuthor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_item);
bookDescription = findViewById(R.id.book_description);
bookAuthor = findViewById(R.id.book_author);
// Recieve data
Intent intent = getIntent();
String Desc = intent.getExtras().getString("Description");
String Author = intent.getExtras().getString("Author");
bookDescription.setText(Desc);
bookAuthor.setText(Author);
}
Book.java
public class Book {
private String mTitle;
private String mDescription;
private String mAuthor;
public Book(){
}
public Book(String mTitle, String mDescription, String mAuthor) {
this.mTitle = mTitle;
this.mDescription = mDescription;
this.mAuthor = mAuthor;
}
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
public String getmDescription() {
return mDescription;
}
public void setmDescription(String mDescription) {
this.mDescription = mDescription;
}
public String getmAuthor() {
return mAuthor;
}
public void setmAuthor(String mAuthor) {
this.mAuthor = mAuthor;
}
}
I want to make the SingleItem class swipeable so that the user can see more content about the book when they swipe.
Use SwipeRefreshLayout in your activity to Swipe down and update textview
<android.support.v7.widget.SwipeRefreshLayout
android:id="#+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.SwipeRefreshLayout>
Then in your Activity.java
TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
mTextView=findViewById(R.id.textView);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mTextView.setText("My new text") // update here
pullToRefresh.setRefreshing(false);
}
});
}
Maybe you'd like to use an SeekBar? It has to be swiped and TextView has to be showing text, not vice versa. Set your SeekBar and TextView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="#dimen/small_padding">
<TextView
android:id="#+id/text_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<SeekBar
android:id="#+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"/>
</LinearLayout>
Then, MainActivity.java:
public class MainActivity extends AppCompatActivity {
TextView textView;
SeekBar seekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_progress);
seekBar = findViewById(R.id.seek_bar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textView.setText("Your progress is " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}

Firestore recycler adapter not fetching document names

I'm trying fetch all documents using FirestoreRecyclerAdapter here if there are 7 documents the RecyclerView items successfully populates with 7 items but here problem is the items which are having a text view are not getting populated with document names. Please take a look at my source code:
FriendsResponse Class:
#IgnoreExtraProperties
public class FriendsResponse {
FirebaseFirestore db;
public String getTable1() {
return Table1;
}
public void setTable1(String table1) {
Table1 = table1;
}
private String Table1;
public FriendsResponse() {
}
public FriendsResponse(String Table1) {
this.Table1 = Table1;
}
}
TableList Fragment where recyclerview is initialized:
public class TableListFragment extends Fragment{
private FirebaseFirestore db;
private FirestoreRecyclerAdapter adapter;
String documentnm;
RecyclerView recyclerView;
FloatingActionButton addt;
private StaggeredGridLayoutManager _sGridLayoutManager;
public static TableListFragment newInstance() {
TableListFragment fragment = new TableListFragment();
return fragment;
}
public TableListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tablelist, container, false);
recyclerView = view.findViewById(R.id.rectab);
addt=view.findViewById(R.id.addtab);
init();
getFriendList();
addt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return view;
}
private void init(){
_sGridLayoutManager = new StaggeredGridLayoutManager(3,
StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(_sGridLayoutManager);
db = FirebaseFirestore.getInstance();
}
private void getFriendList(){
Query query = db.collection("Order");
FirestoreRecyclerOptions<FriendsResponse> response = new FirestoreRecyclerOptions.Builder<FriendsResponse>()
.setQuery(query, FriendsResponse.class)
.build();
adapter = new FirestoreRecyclerAdapter<FriendsResponse, FriendsHolder>(response) {
#Override
public void onBindViewHolder(FriendsHolder holder, int position, FriendsResponse model) {
holder.exname.setText(model.getTable1());
holder.itemView.setOnClickListener(v -> {
Snackbar.make(recyclerView, model.getTable1(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
});
}
#Override
public FriendsHolder onCreateViewHolder(ViewGroup group, int i) {
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.list_item, group, false);
return new FriendsHolder(view);
}
#Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
};
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
public class FriendsHolder extends RecyclerView.ViewHolder {
TextView exname;
public FriendsHolder(View itemView) {
super(itemView);
exname= itemView.findViewById(R.id.topicname);
}
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
}
}
This is the code of list_item:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="#+id/cardvw"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="6dp"
card_view:cardElevation="3dp"
card_view:cardUseCompatPadding="true"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto">
<LinearLayout android:orientation="vertical" android:padding="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/topiclogo"
android:layout_width="match_parent"
android:layout_gravity="center"
android:src="#drawable/table"
android:layout_height="wrap_content"
/>
<TextView android:textSize="15sp"
android:textStyle="bold"
android:textAlignment="center"
android:textColor="#ffffa200"
android:id="#+id/topicname"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
As I understand, you want to set the id of the document to that TextView. So because those names are actually documents ids, you should use the following lines of code inside onBindViewHolder() method:
String id = getSnapshots().getSnapshot(position).getId();
holder.exname.setText(id);
The POJO class that you are using is useful when getting the properties of the documents, not to get the document ids.

RecyclerView OnClick to take to another Fragment

I am stuck with this error for a long time now, I am new to JAVA.
I want to click an item on the RecyclerView (currently on a fragment) that got populated from Firebase. Once I click on it, it should take me to the next fragment by parcing some data and also the position of the item.
Here is my adapter, CustomAdapter.java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
public CustomAdapter(ArrayList<Userpost> data) {
this.data = data;
}
public interface OnItemClickListener{
void onItemClick(Userpost userpost, int activityNumber);
}
private ArrayList<Userpost> data;
private static final int ACTIVITY_NUM = 4;
private OnItemClickListener listener;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView textViewName;
TextView textViewVersion;
SquareImageView imageView;
private final Context context;
public View mCardView;
public MyViewHolder(View itemView) {
super(itemView);
context = itemView.getContext();
this.textViewName = (TextView) itemView.findViewById(R.id.textViewName);
this.textViewVersion = (TextView) itemView.findViewById(R.id.textViewVersion);
this.imageView = (SquareImageView) itemView.findViewById(R.id.imageView);
this.mCardView = itemView.findViewById(R.id.card_view);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "Position is " +getAdapterPosition(),Toast.LENGTH_SHORT).show();
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Log.d(TAG, "MyViewHolder: setting up adapter for profile fragment");
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_layout, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(itemView);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int Position) {
Log.d(TAG, "onBindViewHolder: setting up adapter for profile fragment");
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
final ImageView imageView = holder.imageView;
textViewName.setText(data.get(Position).getPheading());
textViewVersion.setText(data.get(Position).getDescriptionpost());
Picasso.with(holder.imageView.getContext()).load(data.get(Position).getImage_path()).into(holder.imageView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Recycle Click" + Position, Toast.LENGTH_SHORT).show();
listener.onItemClick(data.get(Position), ACTIVITY_NUM);
}
});
}
#Override
public int getItemCount() {
return data.size();
}
}
Here's fragment, ProfileFragment.java
public class ProfileFragment extends Fragment {
private static final String TAG = "ProfileFragment";
private static final int ACTIVITY_NUM = 4;
//firebase stuff
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
private FirebaseMethods mFirebaseMethods;
// Recycler View Widgets
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private static ArrayList<Userpost> data;
private static ArrayList<Integer> removedItems;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile, container, false);
gridView = (GridView) view.findViewById(R.id.gridView);
recyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
cardView = (CardView) view.findViewById(R.id.card_view);
toolbar = (Toolbar) view.findViewById(R.id.profileToolBar);
bottomNavigationView = (BottomNavigationViewEx) view.findViewById(R.id.bottomNavViewBar);
mContext = getActivity();
mFirebaseMethods = new FirebaseMethods(getActivity());
//Recycler View class
super.onCreate(savedInstanceState);
data = new ArrayList<Userpost>();
recyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new CustomAdapter(data);
recyclerView.setAdapter(adapter);
updateArrayList();
private void updateArrayList() {
Log.d(TAG, "updateArrayList: setting up for profile fragment");
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_user_posts))
.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d(TAG, "onChildAdded: explore fragment");
data.add(dataSnapshot.getValue(Userpost.class));
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Userpost model = dataSnapshot.getValue(Userpost.class);
final int index = getItemIndex(model);
data.set(index, model);
adapter.notifyItemChanged(index);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private int getItemIndex(Userpost user) {
Log.d(TAG, "getItemIndex: setting up for profile fragment");
int index = -1;
for (int i = 0; i < data.size(); i++) {
if (data.get(i).image_path.equals(user.image_path)) {
index = i;
break;
}
}
return index;
}
Userpost.java is the model here.
And here is the logcat:
java.lang.NullPointerException: Attempt to invoke interface method 'void sahhaj.com.myapp.CustomAdapter$OnItemClickListener.onItemClick(myap.com.myapp.models.Userpost, int)' on a null object reference
at sahhaj.com.sahhajapp.CustomAdapter$1.onClick(CustomAdapter.java:112)
at android.view.View.performClick(View.java:5721)
at android.view.View$PerformClick.run(View.java:22620)
Your OnItemClickListener listener attribute is never set, so it is Null.
Check where you initialize it, if ever.
Change your RecyclerView array adapter class constructor like below.
public CustomAdapter(ArrayList<Userpost> data, OnItemClickListener listener) {
this.data = data;
this.listener = listener;
}
And in your Fragment change the RecyclerView array adapter object initializing like below.
adapter = new CustomAdapter(data, new CustomAdapter.OnItemClickListener() {
#Override
public void onItemClick(Userpost userpost, int activityNumber) {
// do whatever you want to do
}
});
And that's it. Now run the code you'll get your desired output.
**Call in Get Api **
implementation "com.android.support:cardview-v7:28.0.0"
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
<uses-permission android:name="android.permission.INTERNET" />
android:usesCleartextTraffic="true"
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="#+id/customRecyclerView"
android:layout_height="match_parent"
/>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/coverImage"
android:layout_width="80dp"
android:layout_height="80dp" />
<TextView
android:id="#+id/title"
android:textSize="15dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
public interface ApiInterface
{
#GET("/photos")
Call<List<RetroPhoto>> getAllPhotos();
}
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RestApiClient {
private static Retrofit retrofit;
private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public class RetroPhoto {
#SerializedName("albumId")
private Integer albumId;
#SerializedName("id")
private Integer id;
#SerializedName("title")
private String title;
#SerializedName("url")
private String url;
#SerializedName("thumbnailUrl")
private String thumbnailUrl;
public RetroPhoto(Integer albumId, Integer id, String title, String url, String thumbnailUrl) {
this.albumId = albumId;
this.id = id;
this.title = title;
this.url = url;
this.thumbnailUrl = thumbnailUrl;
}
public Integer getAlbumId() {
return albumId;
}
public void setAlbumId(Integer albumId) {
this.albumId = albumId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
}
private CustomAdapter adapter;
private RecyclerView recyclerView;
ProgressDialog progressDoalog;
progressDoalog = new ProgressDialog(MainActivity.this);
progressDoalog.setMessage("Loading....");
progressDoalog.show();
/*Create handle for the RetrofitInstance interface*/
ApiInterface service = RestApiClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<RetroPhoto>> call = service.getAllPhotos();
call.enqueue(new Callback<List<RetroPhoto>>() {
#Override
public void onResponse(Call<List<RetroPhoto>> call, Response<List<RetroPhoto>> response) {
progressDoalog.dismiss();
generateDataList(response.body());
}
#Override
public void onFailure(Call<List<RetroPhoto>> call, Throwable t) {
progressDoalog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
/*Method to generate List of data using RecyclerView with custom adapter*/
private void generateDataList(List<RetroPhoto> photoList) {
recyclerView = findViewById(R.id.customRecyclerView);
adapter = new CustomAdapter(this, photoList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private List<RetroPhoto> dataList;
private Context context;
public CustomAdapter(Context context,List<RetroPhoto> dataList){
this.context = context;
this.dataList = dataList;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
public final View mView;
TextView txtTitle;
private ImageView coverImage;
CustomViewHolder(View itemView) {
super(itemView);
mView = itemView;
txtTitle = mView.findViewById(R.id.title);
coverImage = mView.findViewById(R.id.coverImage);
}
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.custom_row, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
holder.txtTitle.setText(dataList.get(position).getTitle());
Picasso.get().load(dataList.get(position).getThumbnailUrl()).into(holder.coverImage);
// Picasso.Builder builder = new Picasso.Builder(context);
// builder.downloader(new OkHttp3Downloader(context));
// builder.build().load(dataList.get(position).getThumbnailUrl())
// .placeholder((R.drawable.ic_launcher_background))
// .error(R.drawable.ic_launcher_background)
// .into(holder.coverImage);
}
#Override
public int getItemCount() {
return dataList.size();
}
}

Dialog getActivity not working with Data Binding

I have implemented a ricyvlerview search, and i want to listen for clicks, but context is allways null, i even tryed to move the method to an activity and i got the same result
This is my first time messing arround with Data binding i searched alot here but i can't find what i am doing wrong
item_exemple.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="model"
type="pt.condutorresponsavel.android.testescodigo.Search.models.ExampleModel"/>
<variable
name="handlers"
type="pt.condutorresponsavel.android.testescodigo.Study"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true">
<TextView
android:onClick="#{(v) -> handlers.onCategoryClick(v,model)}"
android:ellipsize="end"
android:lines="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="#{model.text}"/>
<View
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#color/colorPrimary"
android:alpha="0.17"/>
</FrameLayout>
ExampleViewHolder.java
public class ExampleViewHolder extends SortedListAdapter.ViewHolder<ExampleModel> {
private final ItemExampleBinding mBinding;
public ExampleViewHolder(ItemExampleBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
#Override
protected void performBind(ExampleModel item) {
mBinding.setModel(item);
mBinding.setHandlers(new Study());
}
}
Study.java
public class Study extends Fragment {
public static Fragment fragment;
public static SearchView searchView;
Context context;
private final String[] pageNames = {"Favorites", ""};
ViewPager pager;
private OnFragmentInteractionListener mListener;
public Study() { }
public static Estudo newInstance(String param1, String param2) {
Estudo fragment = new Estudo();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_estudo, container, false);
fragment = this;
...
pager = (ViewPager) view.findViewById(R.id.pager);
pager.setAdapter(buildAdapter());
return view;
}
private PagerAdapter buildAdapter() {
return(new SampleAdapter(getActivity(), getChildFragmentManager()));
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
public class SampleAdapter extends FragmentPagerAdapter {
Context ctxt = null;
public SampleAdapter(Context ctxt, FragmentManager mgr) {
super(mgr);
this.ctxt = ctxt;
}
#Override
public int getCount() {
return (2);
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return Favorites.newInstance(position + 1);
}else{
return otherFragment.newInstance(position + 1);
}
}
#Override
public String getPageTitle ( int position){
return (String.valueOf(pageNames[position]));
}
}
public void onCategoryClick(View view, ExampleModel model) {
Log.d("mTag", "Index: " + model.getId());
Dialog dialog = new Dialog(getActivity()); //NullPointerException
dialog.setContentView(R.layout.dialog_pergunta);
dialog.show();
}
public static class Favorites extends Fragment{...} //RecyclerView is in here
public static class otherFragment extends Fragment{...}
}
Problem
public void onCategoryClick(View view, ExampleModel model) {
Log.d("mTag", "Index: " + model.getId());
Dialog dialog = new Dialog(getActivity()); //NullPointerException
dialog.setContentView(R.layout.dialog);
dialog.show();
}
i tried setting the context in onAttach and also tried to use
final Context contex = getActivity();
but nothing worked outside onCategoryClick the context is not null but inside onCategoryClick the context is null
how can i overcome this?
EDIT
if i don't declare my interface static i get this
NullPointerException: Attempt to invoke interface method 'void pt.condutorresponsavel.android.testescodigo.Study$OnItemClic‌​k.onClick(long)' on a null object reference at
pt.condutorresponsavel.android.testescodigo.Study.onCategory‌​Click(Study.java:303‌​)
I was able to fix this, there may be better options to achive the same result but since i am not a expert this was what i come up with.
I created a Interface, on my fragment when the onCategoryClick is called i call a my interface.
static OnItemClick onItemClick;
...
public void onCategoryClick(View view, ExampleModel model) {
onItemClick.onClick(model.getId());
}
public interface OnItemClick{
void onClick(long index);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
onItemClick = new OnItemClick() {
#Override
public void onClick(long index) {
Log.d(TAG, "myIndex: " + index);
Dialog dialog = new Dialog(getActivity());
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setContentView(R.layout.dialog);
}
}

Categories