I'm displaying three recyclerviews inside a fragment. I have recently changed my implementation so I can display some feature on a dropdown menu while long pressing on an item inside one of the three recyclerview.
Since then my app treats the click event on the two first recyclerview incorrectly (out of bound issue) and I know from debbuging that those click events are managed onely by the third adapter.
Here's my fragment code displaying the three recyclerviews:
public class ActivityFragment extends Fragment {
private int Index;
private ForecastRecyclerAdapter FirstView_Adapter;
private ForecastRecyclerAdapter SecondView_Adapter;
private ForecastRecyclerAdapter ThirdView_Adapter;
private CardView FirstCard, SecondCard, ThirdCard;
private LinearLayout SeparatorLayout1, SeparatorLayout2;
private ArrayList<MainViewArrayListRecycler> ListFirstView;
private ArrayList<MainViewArrayListRecycler> ListSecondView;
private ArrayList<MainViewArrayListRecycler> ListThirdView;
public static ActivityFragment newInstance(int Index) {
Bundle args = new Bundle();
ActivityFragment fragment = new ActivityFragment();
args.putInt(GETINDEX, Index);
fragment.setArguments(args);
return fragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View mview = inflater.inflate(R.layout.fragment_mainactivity_forecast, container, false);
if (getArguments() != null) {
Index = getArguments().getInt(GETINDEX);
}
ViewModel viewModel = new ViewModelProvider(this).get(ViewModel.class);
viewModel.getInfo().observe(getViewLifecycleOwner(), Informations -> {
if (Informations != null) {
FillUpArray(Informations.get(Index));
}
});
FirstCard = mview.findViewById(R.id.FirstCard);
SecondCard = mview.findViewById(R.id.SecondCard);
ThirdCard = mview.findViewById(R.id.ThirdCard);
SeparatorLayout1 = mview.findViewById(R.id.SeparatorLayout1);
SeparatorLayout2 = mview.findViewById(R.id.SeparatorLayout2);
RecyclerView FirstView = mview.findViewById(R.id.First_Inside_Recycler);
RecyclerView SecondView = mview.findViewById(R.id.Second_Inside_Recycler);
RecyclerView ThirdView = mview.findViewById(R.id.Third_Inside_Recycler);
FirstView_Adapter = new ForecastRecyclerAdapter();
SecondView_Adapter = new ForecastRecyclerAdapter();
ThirdView_Adapter = new ForecastRecyclerAdapter();
FirstView.setLayoutManager(new LinearLayoutManager(getContext()));
SecondView.setLayoutManager(new LinearLayoutManager(getContext()));
ThirdView.setLayoutManager(new LinearLayoutManager(getContext()));
FirstView.setAdapter(FirstView_Adapter);
SecondView.setAdapter(SecondView_Adapter);
ThirdView.setAdapter(ThirdView_Adapter);
FirstView_Adapter.setOnItemClickListener(new ActivityFragmentAdapter.ActivityFragmentAdapterListener() {
#Override
public void onFirstClick(int position) {
//...
}
#Override
public void onSecondClick(int position) {
//...
}
#Override
public void onThirdClick(int position, boolean isChecked) {
if (isChecked) {
//...
}
}
});
SecondView_Adapter.setOnItemClickListener(new ActivityFragmentAdapter.ActivityFragmentAdapterListener() {
#Override
public void onFirstClick(int position) {
//...
}
#Override
public void onSecondClick(int position) {
//...
}
#Override
public void onThirdClick(int position, boolean isChecked) {
if (isChecked) {
//...
}
}
});
ThirdView_Adapter.setOnItemClickListener(new ActivityFragmentAdapter.ActivityFragmentAdapterListener() {
#Override
public void onFirstClick(int position) {
//...
}
#Override
public void onSecondClick(int position) {
//...
}
#Override
public void onThirdClick(int position, boolean isChecked) {
if (isChecked) {
//...
}
}
});
return mview;
}
private void FillUpArray(Information Info) {
/* Fill up the different arraylist and call setData frome the adapter */
}
}
Here's the recycler adapter class used:
public class ActivityFragmentAdapter extends RecyclerView.Adapter<ActivityFragmentAdapter.InsideRecyclerHolder> {
private ArrayList<MainViewArrayListRecycler> mRecyclerArrayListType;
private static ActivityFragmentAdapterListener mListener;
private String mUnit;
private int mAverageDistance;
private int mCurrentDistance;
private int mPeriodInterval;
public void setData(ArrayList<MainViewArrayListRecycler> RecyclerArrayListType) {
mRecyclerArrayListType = RecyclerArrayListType;
notifyDataSetChanged();
}
#NonNull
#Override
public InsideRecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater myInflater = LayoutInflater.from(parent.getContext());
View myOwnView = myInflater.inflate(R.layout.forecast_recycler, parent, false);
return new InsideRecyclerHolder(myOwnView, mListener);
}
#Override
public void onBindViewHolder(#NonNull InsideRecyclerHolder holder, int position) {
MainViewArrayListRecycler currentItem = mRecyclerArrayListType.get(position);
String tmpConcatDistance;
holder.t1.setText(currentItem.getTitle()));
holder.t2.setText(currentItem.getText());
}
#Override
public int getItemCount() {
return mRecyclerArrayListType.size();
}
public static class InsideRecyclerHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener{
final TextView t1;
final TextView t2;
final CheckBox cb1;
public InsideRecyclerHolder(#NonNull View itemView, final ForecastRecyclerAdapterListener listener) {
super(itemView);
t1 = itemView.findViewById(R.id.t1);
t2 = itemView.findViewById(R.id.t2);
cb1 = itemView.findViewById(R.id.cb1);
cb1.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (listener != null) {
int position = getBindingAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onThirdClick(position, isChecked);
cb1.setChecked(false);
}
}
});
itemView.setOnCreateContextMenuListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
if (mListener != null) {
int position = getBindingAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
switch (item.getItemId()) {
case 1:
mListener.onFirstClick(position);
return true;
case 2:
mListener.onSecondClick(position);
return true;
}
}
}
return false;
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle(R.string.dropdown_menu_title);
MenuItem firstItem = menu.add(Menu.NONE, 1, 1, R.string.dropdown_menu_firstItem);
MenuItem secondItem = menu.add(Menu.NONE, 2, 2, R.string.dropdown_menu_secondItem);
firstItem.setOnMenuItemClickListener(this);
secondItem.setOnMenuItemClickListener(this);
}
}
public interface ActivityFragmentAdapterListener {
void onFirstClick(int position);
void onSecondClick(int position);
void onThirdClick(int position, boolean isChecked);
}
public void setOnItemClickListener(ActivityFragmentAdapterListener listener) {
mListener = listener;
}
}
What can be the issue ?
Related
I am doing an app which auto-scrolls images, at the bottom of the screen there is a static layout, which I need to display the value of images that have already passed (i.e. position).
I get the correct value of images passed by implementing :
int position = holder.getAdapterPosition();
in the RecyclerViewListAdapter.java
now I need to display this value in the RecyclerViewListActivity.java
on a text view at the static layout beneath the Recycler view?
public class RecyclerViewListAdapter extends RecyclerView.Adapter {
Context context;
List<Data> dataList;
private SharedPreferences preferences;
public RecyclerViewListAdapter(Context context, List<Data> dataList) {
this.context = context;
this.dataList = dataList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_recycler_list, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.mImage.setImageResource(dataList.get(position).getImage());
holder.mImage.setImageResource(dataList.get(position).getImage());
**int position = holder.getAdapterPosition();**
}
#Override
public int getItemCount() {
if (dataList == null || dataList.size() == 0)
return 0;
return dataList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView mNumberText,mText;
ImageView mImage;
LinearLayout mLinearLayout;
public MyViewHolder(View itemView) {
super(itemView);
mImage = (ImageView) itemView.findViewById(R.id.quran_page);
mLinearLayout = (LinearLayout) itemView.findViewById(R.id.linearLayout);
}
}
}
public class RecyclerViewListActivity extends AppCompatActivity {
RecyclerView mListRecyclerView;
ArrayList<Data> dataArrayList;
RecyclerViewListAdapter recyclerViewListAdapter ;
Runnable updater;
private boolean isTouch = false;
TextViewRemaining;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view_list);
final TextView TextViewRemaining = (TextView) findViewById(R.id.TextViewRemaining);
**TextViewRemaining.setText("Position: "+position);**
initializeView();
mListRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
mListRecyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(RecyclerViewListActivity.this, "Long press on position :" + position,
Toast.LENGTH_LONG).show();
}
}));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
public static interface ClickListener{
public void onClick(View view,int position);
public void onLongClick(View view,int position);
}
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private ClickListener clicklistener;
private GestureDetector gestureDetector;
//#RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
public RecyclerTouchListener(Context context, final RecyclerView recycleView, final 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=recycleView.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null){
clicklistener.onLongClick(child,recycleView.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) {
}
}
private void initializeView()
{
mListRecyclerView = (RecyclerView) findViewById(R.id.vR_recyclerViewList);
setValues();
}
private void setValues(){
prepareData();
recyclerViewListAdapter = new RecyclerViewListAdapter(RecyclerViewListActivity.this,dataArrayList);
mListRecyclerView.setLayoutManager(new LinearLayoutManager(RecyclerViewListActivity.this)); // original
mListRecyclerView.setItemAnimator(new DefaultItemAnimator());
mListRecyclerView.setHasFixedSize(false);
mListRecyclerView.setAdapter(recyclerViewListAdapter);
recyclerViewListAdapter.notifyDataSetChanged();
final int speedScroll = 2000; //default is 2000 it need to be 30000
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int count = 0;
// boolean flag = true;
#Override
public void run() {
boolean x=true;
// while(x) {
if (count < recyclerViewListAdapter.getItemCount()) {
if (count == recyclerViewListAdapter.getItemCount() - 1) {
flag = false;
} else if (count == 0) {
flag = true;
}
}
if (flag) count++;
// else count--;
mListRecyclerView.smoothScrollToPosition(count);
handler.postDelayed(this, speedScroll);
}
};
handler.postDelayed(runnable,speedScroll);
}
private void prepareData(){
dataArrayList = new ArrayList<>();
Data data1 = new Data();
data1.setImage(R.drawable.p1);
dataArrayList.add(data1);
Data data2 = new Data();
data2.setImage(R.drawable.p2);
dataArrayList.add(data2);
Data data3 = new Data();
data3.setImage(R.drawable.p3);
dataArrayList.add(data3);
Data data4 = new Data();
data4.setImage(R.drawable.p4);
dataArrayList.add(data4);
Data data5 = new Data();
data5.setImage(R.drawable.p5);
dataArrayList.add(data5);
}
}
So, How can I show the position value on textView in a real-time, as position is a dynamic value, I expect the output on the textView to change as the images passed to the top.
Many Thanks in advance.
This how I solve my problem:
I save the position value in a power Preference(an easier version of shared Preferences)-many thanks to:
Ali Asadi(https://android.jlelse.eu/powerpreference-a-simple-approach-to-store-data-in-android-a2dad4ddc4ac)
I use a Thread that updates the textview every second-many thanks to:
https://www.youtube.com/watch?v=6sBqeoioCHE&t=149s
Thanks for all.
I have a recycler view that displays a list of items.
Within each item, there is a title and another RecyclerView that display a list of items.
I want to access the click events of the items of the child RecyclerView.
Screenshot of the layout:
The parent RecyclerView:
public class DetailsGroupAdapter extends RecyclerView.Adapter<DetailsGroupAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
RecyclerView mRecyclerView;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
void onGroupItemLongClick(View itemView, int groupPosition, int itemPosition);
void onGroupItemClick(View itemView, int groupPosition, int itemPosition);
}
public void setOnItemClickListener(OnItemClickListener listener) {
DetailsGroupAdapter.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public CardView cvContainer;
public RecyclerView rvItems;
public ViewHolder(final View itemView)
{
super(itemView);
tvTitle = itemView.findViewById(R.id.group_title);
cvContainer = itemView.findViewById(R.id.container);
rvItems = itemView.findViewById(R.id.rv_group_items);
//click listener setup
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Triggers click upwards to the adapter on click
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
}
public void clearAnimation()
{
cvContainer.clearAnimation();
}
}
private List<DetailsGroup> itemList;
public DetailsGroupAdapter(List<DetailsGroup> itemList)
{
this.itemList = itemList;
}
#Override
public DetailsGroupAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View layoutView = inflater.inflate(R.layout.item_details_group, parent, false);
mRecyclerView = (RecyclerView) parent;
return new ViewHolder(layoutView);
}
#Override
public void onBindViewHolder(final DetailsGroupAdapter.ViewHolder viewHolder, int groupPosition){
final DetailsGroup detailsGroup = itemList.get(groupPosition);
if(detailsGroup.Title != null){
viewHolder.tvTitle.setText(detailsGroup.Title);
} else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
final DetailsGroupItemsAdapter detailsGroupAdapter = new DetailsGroupItemsAdapter(detailsGroup.itemsList, groupPosition);
detailsGroupAdapter.setOnItemClickListener(new DetailsGroupItemsAdapter.OnItemClickListener() {
#Override
public void onItemClick(View itemView, int position) {
if (listener != null){
listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
}
}
#Override
public void onLongClick(View itemView, int position) {
if (listener != null){
listener.onGroupItemLongClick(itemView, (int) itemView.getTag(), position);
}
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context) {};
viewHolder.rvItems.setLayoutManager(linearLayoutManager);
viewHolder.rvItems.setAdapter(detailsGroupAdapter);
}
private void setAnimation(View viewToAnimate, int position)
{
if (position > lastPosition) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
#Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
((ViewHolder)holder).cvContainer.clearAnimation();
}
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
#Override
public int getItemCount()
{
return itemList.size();
}
public void clear() {
itemList.clear();
notifyDataSetChanged();
}
public void addAll(List<DetailsGroup> list){
itemList.addAll(list);
notifyDataSetChanged();
}
}
The child RecyclerView:
public class DetailsGroupItemsAdapter extends RecyclerView.Adapter<DetailsGroupItemsAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
private int groupPosition;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
void onLongClick(View itemView,int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
DetailsGroupItemsAdapter.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public TextView tvSubTitle;
public ImageView ivThumbnail;
public LinearLayout llContainer;
public ViewHolder(final View itemView)
{
super(itemView);
ivThumbnail = itemView.findViewById(R.id.thumbnail);
tvTitle = itemView.findViewById(R.id.title);
tvSubTitle = itemView.findViewById(R.id.subtitle);
llContainer = itemView.findViewById(R.id.container);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (listener != null)
listener.onLongClick(itemView, getLayoutPosition());
return false;
}
});
}
public void clearAnimation()
{
llContainer.clearAnimation();
}
}
private List<ItemDetail> itemList;
public DetailsGroupItemsAdapter(List<ItemDetail> itemList, int groupPosition)
{
this.itemList = itemList;
this.groupPosition = groupPosition;
}
#Override
public DetailsGroupItemsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View layoutView = inflater.inflate(R.layout.item_details, parent, false);
return new ViewHolder(layoutView);
}
#Override
public void onBindViewHolder(DetailsGroupItemsAdapter.ViewHolder viewHolder, int position){
viewHolder.itemView.setTag(groupPosition);
ItemDetail itemDetail = itemList.get(position);
if(itemDetail.Title != null){
viewHolder.tvTitle.setText(itemDetail.Title);
} else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
if(itemDetail.Sub_Title != null){
viewHolder.tvSubTitle.setText(itemDetail.Sub_Title);
} else {
viewHolder.tvSubTitle.setVisibility(View.GONE);
}
if(itemDetail.Thumbnail_Enabled){
PicManipulationUtility.SetGenericPictureFromThumbnailType(viewHolder.ivThumbnail, itemDetail.Thumbnail_Type, itemDetail.Thumbnail);
} else {
viewHolder.ivThumbnail.setVisibility(View.GONE);
}
setAnimation(viewHolder.llContainer, position);
}
private void setAnimation(View viewToAnimate, int position)
{
if (position > lastPosition) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
#Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
((ViewHolder)holder).llContainer.clearAnimation();
}
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
#Override
public int getItemCount()
{
return itemList.size();
}
public void clear() {
itemList.clear();
notifyDataSetChanged();
}
public void addAll(List<ItemDetail> list){
itemList.addAll(list);
notifyDataSetChanged();
}
}
The classes used:
ItemDetail and DetailsGroup are POJOs to convert JSON into objects.
What I managed to do so far to temporarily fix the problem is:
In onBindViewHolder of parent RecyclerView, I grabbed the group position.
Then I passed the group position of the parent down to the child
adapter initializer in (DetailsGroupItemsAdapter)
Finally, in the child onBindViewHolder I set the tag to be the parent
group position(viewHolder.itemView.setTag(groupPosition);)
So in the click event of the child, I can say:
listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
Thus having both the group position and the child position in the bubbled event in my Activity or Fragment.
But I know for sure that the passed group position can change for any reason such as updating group items or removing items.
I want to know if there is a more robust solution to implement the click events of nested items in this case.
I used this https://gist.github.com/riyazMuhammad/1c7b1f9fa3065aa5a46f, especially
CustomItemClickListener.java :
public interface CustomItemClickListener {
public void onItemClick(View v, int position);
}
(Parent) RecyclerView modifications :
public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getPosition());
}
});
return mViewHolder;
}
//[... the other "classical" parts of your code...]
}
Alone, it allowed me to have separate click events on child and parent
With some modifications, it led me to something similar to your "fix", I think, but maybe it'll give you some clues : I am giving the parent position and the parent listener to the child when constructing it, and then a click on the child produces the same behavior as a click on the parent
Child RecyclerView constructor :
public AppsAdapter(ArrayList<PackageInformation.InfoObject> dataSet, CustomOnItemClickListener customItemClickListener, int parentPos) {
appsDataSet = dataSet;
onItemClickListener = customItemClickListener;
parentPosition = parentPos;
}
Child RecyclerView onCreateViewHolder :
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_app, viewGroup, false);
// Create the ViewHolder to return
final AppsAdapter.ViewHolder mViewHolder = new AppsAdapter.ViewHolder(v);
// Add the Listener
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { onItemClickListener.onItemClick(v, parentPosition); }
});
return mViewHolder;
I am new to android, currently I am working on recyclerView implementations. The issue is I want to delete an item after onCreateContextMenu has been called. I am having some problems getting the right reference to my delete option.
Holder Class
public class UploadDrugsHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
//OUR VIEWS
UploadDrugsAdapter uploadDrugsAdapter;
TextView drugName;
ImageView drugImage;
ItemClickListener itemClickListener;
ArrayList<UploadedDrugs> drugs;
public UploadDrugsHolder(View itemView) {
super(itemView);
this.drugName= (TextView) itemView.findViewById(R.id.shopName);
this.drugImage= (ImageView) itemView.findViewById(R.id.model_menu);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener=itemClickListener;
}
#Override
public void onClick(View v) {
this.itemClickListener.onItemClick(v,getLayoutPosition());
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuItem myActionItem = menu.add("delete");
myActionItem.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
// what do i need to write here?
Toast.makeText(itemView.getContext(), "Drug deleted successfully", Toast.LENGTH_SHORT).show();
return false;
}
}
I always put adapter and holder in the same file.
You should do like this:
public class UploadedDrugsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<UploadedDrugs> dataList = new ArrayList<>();
private OnClickUploadedDrugs event;
public UploadedDrugsAdapter (List<UploadedDrugs> dataList, OnClickUploadedDrugs event) {
this.dataList = dataList;
this.event = event;
}
public interface OnClickUploadedDrugs{
void onClickUploadedDrugs(UploadedDrugs uploadedDrugs);
}
public void changeDataSet(List<UploadedDrugs> dataSet){
dataList = dataSet;
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.your_xml_file, parent, false);
return new ViewHolderUploadedDrugs(view);
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
try {
final UploadedDrugs model = dataList.get(position);
final ViewHolderUploadedDrugs vh = (ViewHolderUploadedDrugs) holder;
// configure view values
//Event
vh.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(event != null){
event.onClickUploadedDrugs(model);
}
}
});
}catch (Exception e){
Log.e(getClass().getSimpleName(), "Erro ao exibir informaçeõs", e);
}
}
#Override
public int getItemCount() {
return (null != dataList ? dataList.size() : 0);
}
static class ViewHolderUploadedDrugs extends RecyclerView.ViewHolder {
TextView drugName;
ImageView drugImage;
ViewHolderUploadedDrugs(View itemView) {
super(itemView);
this.drugName= (TextView) itemView.findViewById(R.id.shopName);
this.drugImage= (ImageView) itemView.findViewById(R.id.model_menu);
}
}
public List<UploadedDrugs> getDataList() {
return dataList;
}
public void setEvent(OnClickUploadedDrugs event) {
this.event = event;
}
}
Something like:
drugs.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, drugs.size());
When I extend an Activity this works fine, but when extending ActivityFragment I get an error:
unable to resolve constructor
At this line: BaseViewPagerAdapter<String> adapter = new BaseViewPagerAdapter<String>(this). I'm just fetching the image from a URL and displaying it in an image slider. If anyone knows any links or tutorials feel free to suggest me. Thanks.
HomeActivity.java
public class HomeActivity extends Fragment {
private String[] paths = {"http://reviewsimpact.com/wp-content/uploads/2016/04/Patanjali-products-list-1024x385.png",
"https://4.bp.blogspot.com/-3-qgzGwoQ3o/Vuqb1a0g6RI/AAAAAAAAATc/FZjOTm0VUBgXsw3VnWz3RorARUUUgl32g/s1600/Baba%2BRamdev%2BPatanjali%2BProducts%2BList%2Bwith%2BPrice%2Blatest%2B-%2BTipsmonk.jpg",
"http://patanjalistores.com/wp-content/uploads/2015/08/maxresdefault-1920x692.jpg",
"https://aos.iacpublishinglabs.com/question/aq/700px-394px/poems-fruits-vegetables_8d6a91e11da7d63.jpg?domain=cx.aos.ask.com",
"https://i.ytimg.com/vi/2IVR8BrUESQ/maxresdefault.jpg"};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
AutoScrollViewPager mViewPager = (AutoScrollViewPager) v.findViewById(R.id.viewPager);
mViewPager = (AutoScrollViewPager)v.findViewById(R.id.viewPager);
BaseViewPagerAdapter<String> adapter = new BaseViewPagerAdapter<String>(this) {
#Override
public void loadImage(ImageView view, int position, String url) {
Picasso.with(getActivity().getApplicationContext()).load(url).into(view);
}
#Override
public void setSubTitle(TextView textView, int position, String s) {
textView.setText("");
}
};
mViewPager.setAdapter(adapter);
adapter.add(initData());
return v;
}
private List<String> initData() {
List<String> data = new ArrayList<>();
Picture picture ;
for (int i = 0 ; i < paths.length ;i++){
data.add(paths[i]);
}
return data;
}
}
BaseBaseViewPagerAdapter.java
public abstract class BaseViewPagerAdapter<T> extends PagerAdapter implements ViewPager.OnPageChangeListener{
private List<T> data = new ArrayList<>();
private Context mContext;
private AutoViewPager mView;
private OnAutoViewPagerItemClickListener listener;
public BaseViewPagerAdapter(List<T> t) {
this.data = t;
}
public BaseViewPagerAdapter(Context context, OnAutoViewPagerItemClickListener listener) {
this.mContext = context;
this.listener = listener;
}
public BaseViewPagerAdapter(Context context, List<T> data) {
this.mContext = context;
this.data = data;
}
public BaseViewPagerAdapter(Context context, List<T> data,OnAutoViewPagerItemClickListener listener) {
this.mContext = context;
this.data = data;
this.listener = listener;
}
public void init(AutoViewPager viewPager,BaseViewPagerAdapter adapter){
mView = viewPager;
mView.setAdapter(this);
mView.addOnPageChangeListener(this);
if (data == null || data.size() == 0){
return;
}
//设置初始为中间,这样一开始就能够往左滑动了
int position = Integer.MAX_VALUE/2 - (Integer.MAX_VALUE/2) % getRealCount();
mView.setCurrentItem(position);
if (!mView.isStart()) {
mView.start();
mView.updatePointView(getRealCount());
}
}
public void setListener(OnAutoViewPagerItemClickListener listener) {
this.listener = listener;
}
public void add(T t){
data.add(t);
notifyDataSetChanged();
mView.updatePointView(getRealCount());
}
public void add(List<T> list){
if (data == null) {
data = new ArrayList<>();
}
data.addAll(list);
notifyDataSetChanged();
mView.start();
mView.updatePointView(getRealCount());
}
public void init(List<T> list){
if (data == null) {
data = new ArrayList<>();
}
data.clear();
data.addAll(list);
notifyDataSetChanged();
if (!mView.isStart()) {
mView.start();
mView.updatePointView(getRealCount());
}
}
#Override
public int getCount() {
return (data == null || data.size() == 0 ) ? 0 : Integer.MAX_VALUE;
}
public int getRealCount(){
return data == null ? 0 : data.size();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
ImageView view = (ImageView) LayoutInflater.from(mContext)
.inflate(R.layout.imageview,container,false);
loadImage(view,position, data.get(position % getRealCount()));
container.addView(view);
//设置标题(不知道为什么标题跟图片对不上,所以做了如下处理,有大神看到帮忙看看。。。)
if (mView.getSubTitle() != null){
if (position == 0){
setSubTitle(mView.getSubTitle(),position,data.get((getRealCount() - 1)));
}else {
setSubTitle(mView.getSubTitle(),position,data.get((position - 1) % getRealCount()));
}
}
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onItemClick(position % getRealCount(),data.get(position % getRealCount()));
}
}
});
return view;
}
public abstract void loadImage(ImageView view,int position,T t);
public abstract void setSubTitle(TextView textView,int position,T t);
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mView.onPageSelected(position % getRealCount());
}
#Override
public void onPageScrollStateChanged(int state) {
}
public interface OnAutoViewPagerItemClickListener<T> {
void onItemClick(int position,T t);
}
}
MainActivity.java
public class MainActivity extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
mDrawerLayout.setDrawerShadow(R.drawable.navigation_drawer_shadow, GravityCompat.START);
if (savedInstanceState == null) {
// on first time display view for first nav item
displayView(0);
}
}
private void displayView(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeActivity();
break;
default:
break;
}
if (fragment != null) {
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
}
This question already has answers here:
RecyclerView onClick
(49 answers)
Closed 7 years ago.
Has anyone using RecyclerView found a way to set an onClickListener to items in the RecyclerView?
this my code:
Pasal_Bab.java
public class Pasal_Bab extends Fragment implements SearchView.OnQueryTextListener {
private RecyclerViewEmptySupport rv;
private List<PasalBabModel> mPBH;
private PasalBabAdapter adapter;
private static ArrayList<PasalBabModel> people;
#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.activity_pasal, container, false);
rv = (RecyclerViewEmptySupport) view.findViewById(R.id.rv_pasal);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
rv.setLayoutManager(layoutManager);
rv.setEmptyView(view.findViewById(R.id.empty));
rv.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
String[] locales = Locale.getISOCountries();
mPBH = new ArrayList<>();
for (String countryCode : locales) {
Locale obj = new Locale("Pasalxyz", countryCode);
mPBH.add(new PasalBabModel(obj.getDisplayCountry(), obj.getISO3Country()));
}
adapter = new PasalBabAdapter(mPBH);
rv.setAdapter(adapter);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(item,
new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
adapter.setFilter(mPBH);
return true; // Return true to collapse action view
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true; // Return true to expand action view
}
});
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
final List<PasalBabModel> filteredModelList = filter(mPBH, newText);
adapter.animateTo(filteredModelList);
adapter.setFilter(filteredModelList);
rv.scrollToPosition(0);
return false;
}
private List<PasalBabModel> filter(List<PasalBabModel> models, String query) {
query = query.toLowerCase();
final List<PasalBabModel> filteredModelList = new ArrayList<>();
for (PasalBabModel model : models) {
final String text = model.getpasalbab_p().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
}
PasalBabAdapter.java
public class PasalBabAdapter extends RecyclerView.Adapter<PasalBabVH> {
private List<PasalBabModel> mPasalBabModel;
public PasalBabAdapter(List<PasalBabModel> mPasalBabModel) {
this.mPasalBabModel = mPasalBabModel;
}
#Override
public void onBindViewHolder(PasalBabVH PasalBabVH, int i) {
final PasalBabModel model = mPasalBabModel.get(i);
PasalBabVH.bind(model);
}
#Override
public PasalBabVH onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.pasalbab_row, viewGroup, false);
return new PasalBabVH(view);
}
public void setFilter(List<PasalBabModel> PasalBabModels) {
mPasalBabModel = new ArrayList<>();
mPasalBabModel.addAll(PasalBabModels);
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return mPasalBabModel.size();
}
public void animateTo(List<PasalBabModel> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(List<PasalBabModel> newModels) {
for (int i = mPasalBabModel.size() - 1; i >= 0; i--) {
final PasalBabModel model = mPasalBabModel.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<PasalBabModel> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final PasalBabModel model = newModels.get(i);
if (!mPasalBabModel.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<PasalBabModel> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final PasalBabModel model = newModels.get(toPosition);
final int fromPosition = mPasalBabModel.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public PasalBabModel removeItem(int position) {
final PasalBabModel model = mPasalBabModel.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, PasalBabModel model) {
mPasalBabModel.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final PasalBabModel model = mPasalBabModel.remove(fromPosition);
mPasalBabModel.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
}
PasalBabVH.java
public class PasalBabVH extends RecyclerView.ViewHolder {
public TextView p_TextView;
public TextView b_TextView;
public PasalBabVH(View itemView) {
super(itemView);
p_TextView = (TextView) itemView.findViewById(R.id.uud_pasal);
b_TextView = (TextView) itemView.findViewById(R.id.uud_bab);
}
public void bind(PasalBabModel mx) {
p_TextView.setText(mx.getpasalbab_p());
b_TextView.setText(mx.getpasalbab_b());
}
}
PasalBabModel.java
public class PasalBabModel {
String pasalbab_p;
String pasalbab_b;
public PasalBabModel(String pasalbab_p, String pasalbab_b) {
this.pasalbab_p = pasalbab_p;
this.pasalbab_b = pasalbab_b;
}
public String getpasalbab_p() {
return pasalbab_p;
}
public String getpasalbab_b() {
return pasalbab_b;
}
}
please helpme...i'm a beginner :)
Create the adapter like so:
public class CustomAdapter extends RecyclerView.Adapter<Custom.ViewHolder> {
private List<SomeObject> mDataSet;
public OnItemClickListener mItemClickListener;
private Context mContext;
public CustomAdapter(Context context, List<SomeObject> myDataset, OnItemClickListener mItemClickListener) {
this.mDataSet = myDataset;
this.mItemClickListener = mItemClickListener;
this.mContext = context;
}
public void updateData(List<SomeObject> mDataSet) {
this.mDataSet = mDataSet;
notifyDataSetChanged();
}
public void removeItem(int position) {
mDataSet.remove(position);
notifyItemRemoved(position);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final SomeObject obj = mDataSet.get(position);
holder.name.setText(obj.getName());
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView name;
public ViewHolder(View v) {
super(v);
name = (TextView) v.findViewById(R.id.naam);
v.setOnClickListener(this);
v.setOnLongClickListener(this);
}
#Override
public void onClick(View v) {
// If not long clicked, pass last variable as false.
mItemClickListener.onItemClick(v, getLayoutPosition(), false, mDataSet);
}
#Override
public boolean onLongClick(View v) {
// If long clicked, passed last variable as true.
mItemClickListener.onItemClick(v, getLayoutPosition(), true, mDataSet);
return true;
}
}
public interface OnItemClickListener {
void onItemClick(View view, int position, boolean isLongClick, List<SomeObject> mFilteredList);
}
}
And set the adapter like this:
mAdapter = new CustomAdapter(getActivity(), dataSet, new CustomAdapter.OnItemClickListener() {
#Override
public void onItemClick(View v, int position, boolean isLongClick, List<SomeObject> mDataSet) {
if (isLongClick) {
//Long click
SomeObject obj = mDataSet.get(position);
} else {
//Normal click
SomeObject obj = mDataSet.get(position);
}
}
});
Use interfaces to handle onClicks.
Put this in the adapter:
public interface OnItemClickListener {
void onClickItem(View view, int position);
}
public void SetOnItemClickListener(OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
and then in view holder do this:
public class PasalBabVH extends RecyclerView.ViewHolder {
public TextView p_TextView;
public TextView b_TextView;
public PasalBabVH(View itemView) {
super(itemView);
p_TextView = (TextView) itemView.findViewById(R.id.uud_pasal);
b_TextView = (TextView) itemView.findViewById(R.id.uud_bab);
p_TextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mItemClickListener != null) {
}
}
});
b_TextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mItemClickListener != null) {
}
}
});
}
public void bind(PasalBabModel mx) {
p_TextView.setText(mx.getpasalbab_p());
b_TextView.setText(mx.getpasalbab_b());
}
}
In fragment do this:
adapter.SetOnItemClickListener(new PasalBabAdapter.OnItemClickListener() {
#Override
public void onClickItem(View view, int position) {
}});