I've tried many ways on the net and still can't make it.
How can I replace the those to intent activities?
Here's my main acivity
public class MainActivity extends AppCompatActivity {
private List<firstpageitem> firstpageitemList = new ArrayList<>();
private RecyclerView recyclerView;
private firstpageadapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new firstpageadapter(firstpageitemList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(mAdapter);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
firstpageitem firstpageitem = firstpageitemList.get(position);
Intent intent = new Intent(getApplicationContext(), Animals.class);
startActivity(intent);
}
#Override
public void onLongClick(View view, int position) {
}
}));
preparefirstpageitemData();
}
private void preparefirstpageitemData() {
firstpageitem firstpageitem = new firstpageitem(getString(R.string.firstanimals), "ʕ •ᴥ•ʔ");
firstpageitemList.add(firstpageitem);
firstpageitem = new firstpageitem(getString(R.string.firstflip), "(╯°□°)╯︵ ┻━┻");
firstpageitemList.add(firstpageitem);
firstpageitem = new firstpageitem(getString(R.string.firsthappy), "(ノ^_^)ノ");
firstpageitemList.add(firstpageitem);
firstpageitem = new firstpageitem(getString(R.string.firstmisc), "ⅽ[ː̠̈ː̠̈ː̠̈] ͌");
firstpageitemList.add(firstpageitem);
firstpageitem = new firstpageitem(getString(R.string.firstrage), "(╬゚д゚)");
firstpageitemList.add(firstpageitem);
firstpageitem = new firstpageitem(getString(R.string.firstsad), "。゚ヽ(゚´Д`)ノ゚。");
firstpageitemList.add(firstpageitem);
mAdapter.notifyDataSetChanged();
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private MainActivity.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final MainActivity.ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
and here's my adapter
public class firstpageadapter extends RecyclerView.Adapter{
private List<firstpageitem> firstpageitemList;
public firstpageadapter(List<firstpageitem> firstpageitemList) {
this.firstpageitemList = firstpageitemList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.firstpagerow, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
firstpageitem firstpageitem = firstpageitemList.get(position);
holder.title.setText(firstpageitem.getTitle());
holder.emoticons.setText(firstpageitem.getEmoticons());
}
#Override
public int getItemCount() {
return firstpageitemList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, emoticons;
private final Context context;
public MyViewHolder(View view) {
super(view);
context = itemView.getContext();
title = (TextView) view.findViewById(R.id.title);
emoticons = (TextView) view.findViewById(R.id.emoticons);
}
}
}
firstpage.java
public class firstpageitem {
private String title, emoticons;
public firstpageitem() {
}
public firstpageitem(String title, String emoticons) {
this.title = title;
this.emoticons = emoticons;
}
public String getTitle() {
return title;
}
public void setTitle(String name) {
this.title = name;
}
public String getEmoticons() {
return emoticons;
}
public void setEmoticons(String emoticons) {
this.emoticons = emoticons;
}
}
in place of the toast that you are making you will need to create an Intent and use that to start your new activity.
replace:
Toast.makeText(getApplicationContext(), firstpageitem.getTitle() + " is selected!", Toast.LENGTH_SHORT).show();
with:
Intent intent = new Intent(getApplicationContext(), NewActivityName.class);
startActivity(intent);
NewActivityName is the name of the new activity class you will be starting. It must also be declared in your AndroidManifest.xml. If you want to pass data to the new activity you can use extras which are also covered in the link about intents I included above.
Edit
To get each recycler view item to open a different activity you need to include some data in your firstpageitem about which activity it should open. Here is how you would achieve that.
1) change firstpageitem to have a field that holds the class it should start (actionClass):
public class firstpageitem {
private String title, emoticons;
private Class actionClass; //add this line
public firstpageitem() {}
public firstpageitem(String title, String emoticons, Class actionClass) {
this.title = title;
this.emoticons = emoticons;
this.actionClass = actionClass;
}
public Class getActionClass() {
return actionClass;
}
//.... keep you other getters and setters, I omited them for conciseness.
//....
}
2) populate the actionClass field in your preparefirstpageitemData method. You should use classes for other activities you have already created (ex: AnimalActivity and OtherActivity):
private void preparefirstpageitemData() {
// pass in that new constructor argument, the class the item should start!
firstpageitem firstpageitem = new firstpageitem(getString(R.string.firstanimals), "ʕ •ᴥ•ʔ", AnimalActivity.class);
firstpageitemList.add(firstpageitem);
firstpageitem = new firstpageitem(getString(R.string.firstflip), "(╯°□°)╯︵ ┻━┻", OtherActivity.class);
firstpageitemList.add(firstpageitem);
// And the rest of the items too, I omitted them for conciseness.
}
3) Finally, in your onClick method you will need to get the actionClass for the item that was clicked and use that in your intent:
#Override
public void onClick(View view, int position) {
firstpageitem firstpageitem = firstpageitemList.get(position);
// get the action class here!
Intent intent = new Intent(getApplicationContext(), firstPageItem.getActionClass());
startActivity(intent);
}
PS: I recommend that you use camelCasing for your variables in java and PascalCasing for your classnames. I have a java style guide that you can check out if you are interested, it'll make it easier to maintain your code and get help from others if your code follows those practices.
Related
I've implemented the recyclerView clicklistener using best practices yet it still isn't working. The recyclerview is loading data from the internet using retrofit and should take users to the site where the article was published below is my code:
NOTE: My RecyclerView is a RecyclerView of Cardviews
RecyclerView Adapter
public class NewsArticleAdapter extends RecyclerView.Adapter<NewsArticleAdapter.Viewholder> {
private ArrayList<Article> newsArticles = new ArrayList<>();
private Context context;
private OnArticleListener onArticleListener;
public NewsArticleAdapter(List<Article> newsArticles, Context context, OnArticleListener onArticleListener) {
this.newsArticles = (ArrayList<Article>) newsArticles;
this.context = context;
this.onArticleListener = onArticleListener;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_list_item, parent, false);
Viewholder viewholder = new Viewholder(view, onArticleListener);
return viewholder;
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position) {
Article currentArticle = newsArticles.get(position);
holder.newsHeadline.setText(currentArticle.getTitle());
Glide.with(context)
.load(currentArticle.getUrlToImage())
.placeholder(R.drawable.ic_launcher_foreground)
.into(holder.newsImage);
holder.newsContent.setText(currentArticle.getContent());
// holder.publishedTime.setText(UTCtoLocalDateConverter(currentArticle.getPublishedAt()));
}
#Override
public int getItemCount() {
return newsArticles.size();
}
public class Viewholder extends RecyclerView.ViewHolder implements View.OnClickListener {
OnArticleListener onArticleClickedListner;
TextView newsHeadline;
TextView newsContent;
// TextView publishedTime;
ImageView newsImage;
ConstraintLayout parentLayout;
public Viewholder(#NonNull View itemView, OnArticleListener onArticleListener) {
super(itemView);
newsHeadline = itemView.findViewById(R.id.news_headline_textView);
newsContent = itemView.findViewById(R.id.news_content_textView);
// publishedTime = itemView.findViewById(R.id.published_time_textView);
newsImage = itemView.findViewById(R.id.news_image_view);
parentLayout = itemView.findViewById(R.id.list_item_parent_layout);
onArticleClickedListner = onArticleListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Log.d("RecyclerViewAdapter", "item position clicked: " + getAdapterPosition());
onArticleClickedListner.onArticleClicked(getAdapterPosition());
}
}
/*RecyclerView onItemClickListenerInterface*/
public interface OnArticleListener {
void onArticleClicked(int position);
}
}
MainActivity (Houses RecyclerView)
public class MainActivity extends AppCompatActivity implements NewsArticleAdapter.OnArticleListener {
private RecyclerView newsRecyclerView;
private NewsArticleAdapter newsAdapter;
private NewsAPI NewsAPI;
private ArrayList<Article> newsArticles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newsRecyclerView = findViewById(R.id.newsRecyclerView);
newsAdapter = new NewsArticleAdapter(new ArrayList<Article>(), this, this);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
newsRecyclerView.setLayoutManager(layoutManager);
newsRecyclerView.setAdapter(newsAdapter);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RetrofitClient.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
NewsAPI = retrofit.create(NewsAPI.class);
Call<Example> call = NewsAPI.getRootJSONObject();
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
if (response.isSuccessful()) {
newsArticles = (ArrayList<Article>) response.body().getArticles();
refreshAdapterWithNewsArticles(newsArticles);
} else {
Log.d("MainActivity", "Error in on Response " + String.valueOf(response.code()));
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
Toast.makeText(MainActivity.this, "Error retrieving News Articles :(", Toast.LENGTH_SHORT).show();
}
});
}
/*
*Method used to generate list of data using recyclerView with costom adapter
* */
private void refreshAdapterWithNewsArticles(List<Article> body) {
newsAdapter = null;
newsAdapter = new NewsArticleAdapter(body, this, MainActivity.this);
newsRecyclerView.setAdapter(newsAdapter);
}
#Override
public void onArticleClicked(int position) {
Log.d("MainActivity", "onArticleClicked Was called in MainACtivity");
Article currentArticle = newsArticles.get(position);
Uri articleUri = Uri.parse(currentArticle.getUrl());
Intent intent = new Intent(Intent.ACTION_VIEW, articleUri);
startActivity(intent);
}
}
Inspired by the code provided in this answer from Jacob Tabak, in your mainActivity under onCreate method.
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(MainActivity.this, recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
//whatever you want to do with position
}
#Override
public void onLongItemClick(View view, int position) {
//whatever you want to do with position
}
}));
and create a new class name it RecyclerItemClickListener
and paste this
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
GestureDetector mGestureDetector;
private OnItemClickListener mListener;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}}
It is a custom RecyclerItemClickListener.
Why don't you try the listener from the onBindViewHolder() method?
holder.your_layout_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onArticleClickedListner.onArticleClicked(position);
}
});
If you have any confusion I can explain it more clear. If you solved it you can accept the answer.
I want to take textview data from recycler view to another activity.I want to take
workshop_name TextView to Otheractivity.
Here is my code.
MechSearchActivity.java
public class MechSearchActivity extends AppCompatActivity {
List<SearchResponse.WorkshopDataBean> workshopList;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_mec);
recyclerView = (RecyclerView) findViewById(R.id.rv_workshoplist);
callSearchApi();
onItemClick();
}
public void callSearchApi() {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<SearchResponse> call = apiService.getSearchData( "workshop_name","image", "street", "locality", "city"); // single search for all the values
call.enqueue(new Callback<SearchResponse>() {
#Override
public void onResponse(Call<SearchResponse> call, retrofit2.Response<SearchResponse> response) {
SearchResponse searchResponse = response.body();
workshopList = searchResponse.getWorkshopData();
MechanicRecyclerAdapter adapter = new MechanicRecyclerAdapter(MechSearchActivity.this, workshopList);
recyclerView.setAdapter(adapter);
LinearLayoutManager mGridLayoutManager = new LinearLayoutManager(MechSearchActivity.this); // (Context context, int spanCount)
recyclerView.setLayoutManager(mGridLayoutManager);
}
#Override
public void onFailure(Call<SearchResponse> call, Throwable t) {
}
});
}
private void onItemClick() {
final GestureDetector mGestureDetector = new GestureDetector(MechSearchActivity.this, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
recyclerView_ws.addOnItemTouchListener(new
RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
View child = recyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
int position = recyclerView.getChildPosition(child);
String workshop_name = workshopList.get(position).getWorkshop_name();
Intent intent = new Intent(MechSearchActivity.this, OtherActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("workshop_name", workshop_name);
startActivity(intent);
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
}
}
MechRecyclerAdapter.java
public class MechanicRecyclerAdapter extends RecyclerView.Adapter<MechanicRecyclerAdapter.MyViewHolder> {
private static final String TAG = MechanicRecyclerAdapter.class.getSimpleName();
Context mContext;
private LayoutInflater inflater;
String vehicle_type;
List<SearchResponse.WorkshopDataBean> workshopList;
public MechanicRecyclerAdapter(Context context, List<SearchResponse.WorkshopDataBean> workshopList) {
inflater = LayoutInflater.from(context);
this.workshopList = workshopList;
mContext = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.single_workshop, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
SearchResponse.WorkshopDataBean current = workshopList.get(position);
String ws_name = workshopList.get(position).getWorkshop_name();
holder.tv_workshopname.setText(ws_name);
}
#Override
public int getItemCount() {
return workshopList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
SearchResponse.WorkshopDataBean current;
TextView tv_workshopname;
public MyViewHolder(View itemView) {
super(itemView);
tv_workshopname = (TextView) itemView.findViewById(workshop_name);
}
}
}
OtherActivity.java
public class OtherActivity extends AppCompatActivity {
TextView SingleWorkshopName;
String workshop_name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.otheractivity);
SingleWorkshopName=(TextView)findViewById(R.id.single_workshop_name);
Bundle extras = getIntent().getExtras();
workshop_name = extras.getString("workshop_name", null);
}
}
For that you need to create one interface in your MechanicRecyclerAdapter
public interface OnListItemClick {
void onItemClick(int position);
}
in onBindViewHolder() assign your click by using following code
viewHolder.main_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onListItemClick.onItemClick(position);
}
});
Implements this interface in you MechSearchActivity you will get onItemClick() method in your activity using position you will get proper name of row and pass to other activity using intent.putExtra("workshop_name", workshop_name);
So i need to start an activity when i click on different rows of recyclerview. I just cant figure out how I tried this code
but seems to be not working
class MyViewholder extends RecyclerView.ViewHolder implements View.OnClickListener{
private final Context context;
public MyViewholder(View itemView) {
super(itemView);
context = itemView.getContext();
}
#Override
public void onClick(View view) {
final Intent intent;
switch (getAdapterPosition()){
case 0:
intent = new Intent(context, CalendarControllerFrancisco.class);
break;
case 1:
intent = new Intent(context, CalendarControllerB.class);
break;
case 2:
intent = new Intent(context, CalendarControllerNa.class);
break;
default:
intent = new Intent(context, CalendarController.class);
break;
}
context.startActivity(intent);
public class LocationAdapter extends RecyclerView.Adapter {
private ArrayList<LocationModel> dataSet;
Boolean check = false;
public class MyViewHolder extends RecyclerView.ViewHolder {
//private final Context context;
TextView locat;
public MyViewHolder(View itemView) {
super(itemView);
// context = itemView.getContext();
this.locat = (TextView)itemView.findViewById(R.id.wordtext);
}
}
public LocationAdapter(ArrayList<LocationModel> data) {
this.dataSet = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_view_row,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
TextView word1 = holder.locat;
word1.setText(dataSet.get(position).getLocations());
}
#Override
public int getItemCount() {
return dataSet.size();
}
You need add setOnClickListener event for one component.
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
TextView word1 = holder.locat;
word1.setText(dataSet.get(position).getLocations());
word.setOnClickListener(holder);
}
RecyclerItemClickListener
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
Define ClickListener as same as ListView onItemClickListener
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
#Override public void onItemClick(View view, int position) {
// TODO Handle item click
}
})
);
This is wrong:
#Override
public void onClick(View view) {
final Intent intent;
switch (getAdapterPosition()){
case 0:
intent = new Intent(context, CalendarControllerFrancisco.class);
break;
case 1:
intent = new Intent(context, CalendarControllerB.class);
break;
case 2:
intent = new Intent(context, CalendarControllerNa.class);
break;
default:
intent = new Intent(context, CalendarController.class);
break;
}}
The ViewHolder is a container used by the adapter to fill in item data arbitrarily depending on the RecyclerView items to be displayed. Hence it shouldn't have access to any position data from the item list to identify itself. You are confusing concepts.
Try replacing the above with something like:
class MyViewholder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final Context context;
int type;
public MyViewholder(View itemView) {
super(itemView);
context = itemView.getContext();
}
public void bind(int type) {
this.type = type;
}
#Override
public void onClick(View view) {
final Intent intent;
switch (this.type){
case 0:
intent = new Intent(context, CalendarControllerFrancisco.class);
break;
case 1:
intent = new Intent(context, CalendarControllerB.class);
break;
case 2:
intent = new Intent(context, CalendarControllerNa.class);
break;
default:
intent = new Intent(context, CalendarController.class);
break;
}
}
}
Then, in your Adapter use onBindViewHolder callback to access the item collection and assign their type for the creation of every item.
Something like:
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.bind(myItemList.get(position).type());
}
I have this adapter class where I have an object with a list in it.
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
private Context context;
private Shop shop;
public ProductAdapter(Context context, Shop shop) {
this.context = context;
this.shop = shop;
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.product_row, parent, false);
return new ProductViewHolder(v);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
holder.tvProductTitle.setText(shop.products.get(position).getTitle());
holder.tvProductDescription.setText(shop.products.get(position).getDescription());
Glide.with(context)
.load(shop.products.get(position).getImageUrl())
.placeholder(android.R.drawable.ic_menu_upload_you_tube)
.error(android.R.drawable.stat_notify_error)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.into(holder.ivProduct);
}
#Override
public int getItemCount() {
if (shop.products != null) {
return shop.products.size();
}
return 0;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
private TextView tvProductTitle, tvProductDescription;
private ImageView ivProduct;
public ProductViewHolder(View itemView) {
super(itemView);
tvProductTitle = (TextView) itemView.findViewById(R.id.tvProductTitle);
tvProductDescription = (TextView) itemView.findViewById(R.id.tvProductDescription);
ivProduct = (ImageView) itemView.findViewById(R.id.ivProduct);
}
}
public interface ClickListener {
void onClick(View v, int position);
void onLongClick(View v, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ProductAdapter.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ProductAdapter.ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
I use this adapter in my fragment where I can click an item from the recyclerview which will open another activity with the selected product and it's parametars. Instead of clicking the whole item, I would like to click on part of it (lets say imageview) which will do the same as it is doing now. But, I would also like to put a checkbox in the recyclerview item itself which will have different function. At the moment, I can't use an intent in the adapter class. The way it is set up now I can only click the whole item. How can I make it work like I explained above?
public class ProductsFragment extends android.support.v4.app.Fragment {
private RecyclerView rvProduct;
private RecyclerView.LayoutManager layoutManager;
private ProductAdapter productAdapter;
public static ProductsFragment newInstance(Bundle args) {
ProductsFragment fragment = new ProductsFragment();
fragment.setArguments(args);
return fragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_products, container, false);
rvProduct = (RecyclerView) v.findViewById(R.id.rvProduct);
rvProduct.setHasFixedSize(true);
layoutManager = new GridLayoutManager(getContext(), 2);
rvProduct.setLayoutManager(layoutManager);
Bundle bundle = getArguments();
final Shop shop = (Shop) bundle.getSerializable("shop");
productAdapter = new ProductAdapter(getContext(), shop);
rvProduct.setAdapter(productAdapter);
productAdapter.notifyDataSetChanged();
rvProduct.addOnItemTouchListener(new ProductAdapter.RecyclerTouchListener(getContext(), rvProduct, new ProductAdapter.ClickListener() {
#Override
public void onClick(View v, int position) {
Intent details = new Intent(getContext(), ProductDetailsActivity.class);
details.putExtra("product", shop.products.get(position));
startActivity(details);
}
#Override
public void onLongClick(View v, int position) {
}
}));
return v;
}
}
EDIT:
I've managed to do this, please tell me if this is right and efficient way:
holder.tvProductTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, ProductDetailsActivity.class);
i.putExtra("product", shop.products.get(position));
context.startActivity(i);
}
});
The way you doing it is not correct.
As your onBindViewHolder will be called repeatedly as you scroll through the list, every time a new listener will be set.
Instead you should set the listeners in the ViewHolder class of Adapter. And use getAdapterPosition() method to get the position of item clicked.
For example:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
private Context context; private Shop shop;
public ProductAdapter(Context context, Shop shop) {
this.context = context;
this.shop = shop;
}
#Override public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.product_row, parent, false);
return new ProductViewHolder(v);
}
#Override public void onBindViewHolder(ProductViewHolder holder, int position) {
holder.tvProductTitle.setText(shop.products.get(position).getTitle());
holder.tvProductDescription.setText(shop.products.get(position).getDescription());
Glide.with(context) .load(shop.products.get(position).getImageUrl()) .placeholder(android.R.drawable.ic_menu_upload_you_tube) .error(android.R.drawable.stat_notify_error) .diskCacheStrategy(DiskCacheStrategy.RESULT) .into(holder.ivProduct);
}
#Override public int getItemCount()
{
if (shop.products != null) {
return shop.products.size();
} return 0;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
private TextView tvProductTitle, tvProductDescription;
private ImageView ivProduct;
public ProductViewHolder(View itemView)
{
super(itemView);
tvProductTitle = (TextView) itemView.findViewById(R.id.tvProductTitle);
tvProductDescription = (TextView) itemView.findViewById(R.id.tvProductDescription);
ivProduct = (ImageView) itemView.findViewById(R.id.ivProduct);
// Set onclickListener on image
ivProduct.setOnCliCkListener(new onClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(context, ProductDetailsActivity.class);
i.putExtra("product",
shop.products.get(getAdapterPosition()));
context.startActivity(i);
}
}
}
}
public interface ClickListener {
void onClick(View v, int position);
void onLongClick(View v, int position);
}
}
You can add click listeners to each respective view of the inflated item in public onBindViewHolder. Did you consider that?
Edit: Ok it's what you did. I don't know about the efficiency though, but this is the way I would do it.
I have a recycler view that has many items that I want to intent from every item to specific activities. I tried many ways but all fail to intent to the activities.
This is the adapter:
public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
private ArrayList<String> itemsData;
public ItemsAdapter(ArrayList<String> itemsData) {
this.itemsData = itemsData;
}
#Override
public ItemsAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent,
int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, null);
final ViewHolder viewHolder = new ViewHolder(itemLayoutView);
itemLayoutView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String word = viewHolder.txtViewTitle.getText().toString();
Toast.makeText(parent.getContext(),word,Toast.LENGTH_LONG).show();
}
});
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.txtViewTitle.setText(itemsData.get(position));
viewHolder.imgViewIcon.setImageResource(R.drawable.imsge_profile);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtViewTitle;
public ImageView imgViewIcon;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
}
}
#Override
public int getItemCount() {
return itemsData.size();
}
}
This is main_activity:
public class MainActivity extends ActionBarActivity {
Toolbar tBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tBar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(tBar);
getSupportActionBar().setTitle("AdroidCode Recycler View");
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
ArrayList<String> listItems = new ArrayList<String>();
listItems.add("Tom");
listItems.add("Hamdy");
listItems.add("John");
listItems.add("Hasna");
listItems.add("Fadi");
listItems.add("Samer");
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ItemsAdapter mAdapter = new ItemsAdapter(listItems);
recyclerView.setAdapter(mAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
}
i tried this instead of the Toast but dosent work
#Override
public void onClick(View v) {
final Intent intent;
switch (getPostion()){
case 0:
intent = new Intent(context, FirstActivity.class);
break;
case 1:
intent = new Intent(context, SecondActivity.class);
break;
...
default:
intent = new Intent(context, DefaultActivity.class);
break;
}
context.startActivity(intent);
}
new adapter
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> {
public static class PersonViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView personName;
TextView personAge;
ImageView personPhoto;
public PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
personName = (TextView)itemView.findViewById(R.id.person_name);
personAge = (TextView)itemView.findViewById(R.id.person_age);
personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
recyclerview.addOnItemTouchListener(new RecyclerItemClickListener(
context, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// TODO Auto-generated method stub
final Intent intent;
switch (position) {
case 0:
intent = new Intent(context, secoundActivity.class);
break;
}
}
));
}}
}
List<Person> persons;
RVAdapter(List<Person> persons){
this.persons = persons;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
PersonViewHolder pvh = new PersonViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
personViewHolder.personName.setText(persons.get(i).name);
personViewHolder.personAge.setText(persons.get(i).age);
personViewHolder.personPhoto.setImageResource(persons.get(i).photoId);
}
#Override
public int getItemCount() {
return persons.size();
}
}
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
#Override public void onItemClick(View view, int position) {
// do whatever
}
})
);
I think you need to add click listener when you intialilize recycler view.Try these
public class RecyclerItemClickListener implements
RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context,
OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context,
new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null
&& mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView,
view.getChildPosition(childView));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
}
You can not direct use onclick. I have found a solution and it's works for me. Try it. I hope it will helps you.
Step 1: Fist add this RecyclerItemClickListener class to your package.
public class RecyclerItemClickListener implements
RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context,
OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context,
new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null
&& mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView,
view.getChildPosition(childView));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
}
Step 2: Now use onclick method. this gives you position of item clicked. Once you get position than you can use it as per your requirement.
recyclerview.addOnItemTouchListener(new RecyclerItemClickListener(
context, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, position + "",
Toast.LENGTH_SHORT).show();
final Intent intent;
switch (position) {
case 0:
Toast.makeText(context, "case 0",
Toast.LENGTH_SHORT).show();
intent = new Intent(context,FirstActivity.class);
break;
case 1:
Toast.makeText(context, "case 1",
Toast.LENGTH_SHORT).show();
intent = new Intent(context,SecondActivity.class);
break;
default:
intent = new Intent(context,DefaultActivity.class);
break;
}
}));