Reputation: 508
I created list using Recycler View. Now I want to get item after click. I heard about getAdapterPosition but I dont know how to use it. I try something like this but honestly dont know how to get it.
My Fragment class code:
public class FragmentOne extends Fragment {
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private List<MovieDb> data;
private MovieDb movieDb;
static View.OnClickListener myOnClickListener;
public static FragmentOne newInstance() {
FragmentOne fragment = new FragmentOne();
return fragment;
}
public class MovieTask extends AsyncTask<Void, Void, List<MovieDb>> {
@Override
protected List<MovieDb> doInBackground(Void... voids) {
MovieResultsPage movies = new TmdbApi("f753872c7aa5c000e0f46a4ea6fc49b2").getMovies().getUpcoming("en-US", 1, "US");
List<MovieDb> listMovies = movies.getResults();
return listMovies;
}
@Override
protected void onPostExecute(List<MovieDb> movieDb) {
data = movieDb;
adapter = new CustomAdapter(data);
recyclerView.setAdapter(adapter);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View returnView = inflater.inflate(R.layout.fragment_one, container, false);
myOnClickListener = new MyOnClickListener(getContext());
recyclerView = (RecyclerView) returnView.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext()); // ???
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
MovieTask mt = new MovieTask();
mt.execute();
return returnView;
}
private class MyOnClickListener implements View.OnClickListener {
private final Context context;
private MyOnClickListener(Context context) {
this.context = context;
}
@Override
public void onClick(View v) {
int pos1;
pos1 = adapter.getItemId();
movieDb = data.get(pos);
TextView text;
text = (TextView) v.findViewById(R.id.text1);
Toast.makeText(getActivity(), text.getText(), LENGTH_SHORT).show();
}
}
}
Function OnClick is mess because I try a lot. I can get text from TextView but it is not what I want.
There is my Adapter class:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private List<MovieDb> dataSet;
public int pos;
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textViewName;
TextView textViewVersion;
ImageView imageViewIcon;
int pos;
public MyViewHolder(View itemView) {
super(itemView);
this.textViewName = (TextView) itemView.findViewById(R.id.text1);
this.textViewVersion = (TextView) itemView.findViewById(R.id.text2);
this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(FragmentOne.myOnClickListener);
}
}
public CustomAdapter(List<MovieDb> data) {
this.dataSet = data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_layout, parent, false);
//view.setOnClickListener(FragmentOne.myOnClickListener);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
pos = holder.getAdapterPosition();
ImageView imageView = holder.imageViewIcon;
Glide.with(imageView).load("https://image.tmdb.org/t/p/w500" + dataSet.get(listPosition).getPosterPath()).into(imageView);
textViewName.setText(dataSet.get(listPosition).getOriginalTitle());
textViewVersion.setText(dataSet.get(listPosition).getReleaseDate());
}
public int getPos(){
return pos;
}
@Override
public int getItemCount() {
if(dataSet == null){
return 0;
}
return dataSet.size();
}
}
I try to get position using int pos
but I dont know how to use it in function OnClick.
Upvotes: 1
Views: 1542
Reputation: 1001
Create an interface to retrieve a MovieDb when clicked:
public interface OnMovieDbClicked {
void movieDbClicked(MovieDb movieDb);
}
In your adapter create a private member of this interface and a setter:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private OnMovieDbClicked onMovieDbClicked;
public setOnMovieDbClicked(OnMovieDbClicked onMovieDbClicked) {
this.onMovieDbClicked = onMovieDbClicked;
}
}
You can then use getAdapterPosition()
in the constructor of your ViewHolder and use onMovieDbClicked
to send the item clicked to your fragment:
public class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
// Initialize your views
itemView.setOnClickListener(view -> {
int pos = getAdapterPosition();
if (onMovieDbClicked != null && pos != RecyclerView.NO_POSITION) {
MovieDb movieDb = dataSet.get(pos);
onMovieDbClicked.movieDbClicked(movieDb);
}
});
}
}
When you're creating your adapter in your fragment, call setOnMovieDbClicked()
as well:
adapter = new CustomAdapter(data);
adapter.setOnMovieDbClicked(movieDb -> {
// Do whatever you want with movieDb
});
Upvotes: 1
Reputation: 23483
I would do something along these lines:
Adjust your MyOnClickListener
to something like this:
private class MyOnClickListener implements View.OnClickListener {
private final Context context;
private int position;
//Adjust your constructor to take in the context as a paramater
private MyOnClickListener(Context context, int position) {
this.context = context;
this.position = position;
}
@Override
public void onClick(View v) {
//not sure what you're doing with movieDB here....
movieDb = data.get(position);
TextView text;
text = (TextView) v.findViewById(R.id.text1);
Toast.makeText(getActivity(), text.getText(), LENGTH_SHORT).show();
}
} }
Update your CustomAdapter
class:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private List<MovieDb> dataSet;
public int pos;
private Context context;
public CustomAdapter(List<MovieDb> data, Context context) {
this.dataSet = data;
this.context = context;
}
//You'll need this later to update the data set
public void updateDataSet(List<MovieDB data){
this.dataSet = data;
notifyDataSetChange();
...
In your onBindViewHolder
do something like:
@Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
pos = holder.getAdapterPosition();
ImageView imageView = holder.imageViewIcon;
Glide.with(imageView).load("https://image.tmdb.org/t/p/w500" + dataSet.get(listPosition).getPosterPath()).into(imageView);
textViewName.setText(dataSet.get(listPosition).getOriginalTitle());
textViewVersion.setText(dataSet.get(listPosition).getReleaseDate());
holder.setOnClickListener(new MyOnclickListener(context, listPosition));
}
Move your adapter call from the MovieTask
to the FragmentOne
onCreateMethod
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View returnView = inflater.inflate(R.layout.fragment_one, container, false);
myOnClickListener = new MyOnClickListener(getContext());
recyclerView = (RecyclerView) returnView.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext()); // ???
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new CustomAdapter(getContext(), data);
MovieTask mt = new MovieTask();
mt.execute();
return returnView;
}
In your Movie Task
update you data set:
@Override
protected void onPostExecute(List<MovieDb> movieDb) {
data = movieDb;
adapter.updateDataSet(data);
}
You might need to make some minor adjustments to this code, but it should give you a basic idea of how to accomplish what you are trying to do.
Best of luck :)
Upvotes: 1