I have an Adapter (A ViewHolder) Class, and when a Button is pressed I'd like to update a TextView of the Home() activity, preferrably without launching the activity immediatly.
The code in the Adapter:
public class GameViewAdapter extends RecyclerView.Adapter<GameViewAdapter.GameViewHolder> {
public static Object OnItemClickListener;
private ArrayList<GameItem> mGameList;
private OnItemClickListener mListener;
public static MyCallback callback;
public GameViewAdapter(ArrayList<GameItem> mGameList, GameViewAdapter.OnItemClickListener mListener, MyCallback callback) {
this.mGameList = mGameList;
this.mListener = mListener;
this.callback = callback;
}
#Override
public GameViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
Context context = viewGroup.getContext();
View v = LayoutInflater.from(context).inflate(R.layout.game_entry, viewGroup, false);
GameViewHolder GVH = new GameViewHolder(v, mListener);
return GVH;
}
#Override
public void onBindViewHolder(#NonNull GameViewHolder gameViewHolder, int position) {
gameViewHolder.bind(mGameList.get(position));
}
#Override
public int getItemCount() {
return mGameList.size();
}
class GameViewHolder extends RecyclerView.ViewHolder {
private ImageView itemCover;
private TextView itemTitle;
private TextView itemDescription;
private PopupWindow popupWindow;
private ImageView popUpImage;
private TextView PopUpTitle;
private EditText customAmount;
private Button add;
private Button addcustom;
private Button exit;
public GameViewHolder(View itemView, GameViewAdapter.OnItemClickListener mListener) {
super(itemView);
setupViews(itemView);
}
public void bind(final GameItem gameItem) {
Glide.with(this.itemCover).load(gameItem.getCover()).into(this.itemCover);
this.itemTitle.setText(gameItem.getTitle());
this.itemDescription.setText(gameItem.getDescription());
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showPopUp(itemView, gameItem);
}
});
}
private void setupViews(View itemView) {
addcustom = itemView.findViewById(R.id.addcustom);
popUpImage = itemView.findViewById(R.id.popupimg);
PopUpTitle = itemView.findViewById(R.id.popuptitle);
customAmount = itemView.findViewById(R.id.gameamount);
itemCover = itemView.findViewById(R.id.GameCover);
itemTitle = itemView.findViewById(R.id.GameTitle);
itemDescription = itemView.findViewById(R.id.GameAmount);
exit = itemView.findViewById(R.id.exit);
}
private void showPopUp(final View itemView, final GameItem gameItem) {
//Declaration
final View popupView = LayoutInflater.from(itemView.getContext()).inflate(R.layout.popup, null);
final PopupWindow popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
final ImageView popupItemCover = popupView.findViewById(R.id.popupimg);
final TextView popupItemTitle = popupView.findViewById(R.id.popuptitle);
//Set Data
Glide.with(popupItemCover).load(gameItem.getCover()).into(popupItemCover);
popupItemTitle.setText(gameItem.getTitle());
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
//ExitButton
exit = popupView.findViewById(R.id.exit);
exit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
add = popupView.findViewById(R.id.addaverage);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.onDataChanged(Integer.valueOf(gameItem.getTime()));
Toast.makeText(popupView.getContext(), String.valueOf(gameItem.getTime()), Toast.LENGTH_SHORT).show();
}
});
}
}
public interface MyCallback {
void onDataChanged(Integer gameTime);
}
public interface OnItemClickListener {
void onGameClick(int position);
}
}
And I have implemented this in the Main Activity:
public void onDataChanged(int gameTime) {
// it will fire when you call your callback.onDataChanged(); in your adapter
// here can change your textview
GameTime.setText(Integer.valueOf(gameTime));
}
}
I've tried to use BroadcastReceiver as well, with no success.
Thank you!
EDIT:
When adding the callback my App crashes with following traceback:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.reogen.gametime.Adapters.GameViewAdapter$MyCallback.onDataChanged(java.lang.String)' on a null object reference
at com.reogen.gametime.Adapters.GameViewAdapter$GameViewHolder$3.onClick(GameViewAdapter.java:127)
Line 127 is: callback.onDataChanged(Integer.valueOf(gameItem.getTime()));
You can create observable like:
in your Adapter create:
public interface IMyCallback {
void onDataChanged(int gameTime);
}
Global field in Adapter:
private IMyCallback callback
Inside constructor of Adapter
public MyAdapter(... , IMyCallback callback) {
...
this.callback = callback;
}
Now your activity make implements IMyCallback and override method onDataChanged.
And when you create your adapter send as callback YourActivity.this.
finnaly you need to make like:
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.onDataChanged(Integer.valueOf(gameItem.getTime()));
}
after this call you will get update in your override method onDataChanged in your activity class. enjoy
------------ Update -----------
in your activity, when you will implements interface you will get method like
#Override
public void onDataChanged(int gameTime) {
// it will fire when you call your callback.onDataChanged(); in your adapter
// here can change your textview
textview.setText(String.valueOf(gameTime));
}
Related
I made a recycler view inside the recycler view. And when I select the inside recycler view, the dialog is displayed, and I want to configure the recycler view in that dialog. I made a dialog and succeeded in displaying the dialog. but I don't know how to make a recycler view in a dialog. please help me.
Dialog class
public class RoomDialog extends Dialog {
private EditText etStudentName, etStudentNumber;
private Button btnConfirm, btnCancel;
private Context context;
private CustomDialogClickListener clickListener;
private Retrofit retrofit;
public EditText getEtStudentName() {
return etStudentName;
}
public EditText getEtStudentNumber() {
return etStudentNumber;
}
public Button getBtnConfirm() {
return btnConfirm;
}
public Button getBtnCancel() {
return btnCancel;
}
public RoomDialog(#NonNull Context context) {
super(context);
this.context = context;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_room);
etStudentName = findViewById(R.id.et_room_Studentname);
etStudentNumber = findViewById(R.id.et_room_studentNumber);
btnConfirm = findViewById(R.id.btn_room_confrim);
btnCancel = findViewById(R.id.btn_room_cancel);
btnConfirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
}) ;
btnCancel.setOnClickListener( new View.OnClickListener(){
#Override
public void onClick(View v) {
dismiss();
}
});
}
}
Inner recycler view
public class RoomAdapter extends RecyclerView.Adapter<RoomAdapter.CustomViewHolder> {
private Context context;
private ArrayList<RoomData> rooms;
public ArrayList<StudnetInRoomData> students;
private LayoutInflater inflater;
public RoomAdapter(Context context, ArrayList<RoomData> rooms) {
this.context = context;
this.rooms = rooms;
this.inflater = LayoutInflater.from(context);
students = new ArrayList<>();
}
#Override
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
view = inflater.inflate(R.layout.single_room, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CustomViewHolder holder, int position) {
RoomData room = rooms.get(position);
holder.tvRoomNum.setText(String.valueOf(room.roomNum));
}
#Override
public int getItemCount() {
return rooms.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView tvRoomNum;
public TextView tvRoomTitle;
public CustomViewHolder(View itemView) {
super(itemView);
tvRoomNum = (TextView) itemView.findViewById(R.id.tvRoomNumber);
tvRoomTitle = (TextView) itemView.findViewById(R.id.tv_room_title);
tvRoomNum.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
RoomDialog roomDialog = new RoomDialog(context);
roomDialog.setCanceledOnTouchOutside(true);
roomDialog.setCancelable(true);
roomDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
roomDialog.show();
}
});
}
}
}
Problem: I am trying to implement three different OnClickListeners via floating action buttons into every item of a recycler view. Each of the three FABs does something different so they need different OnClickListeners. I think I am able to instantiate one with my current adapter setup, but I would like to be able to access all three in the fragment via something like this:
mRecyclerView2.addItemDecoration(itemDecoration2);
mLayoutManager2 = new GridLayoutManager(mContext, 3);
mRecyclerView2.setLayoutManager(mLayoutManager2);
mAdapter2 = new photo_adapter2(mContext, arrayList2);
mRecyclerView2.setAdapter(mAdapter2);
mAdapter2.floatingActionButtonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = mRecyclerView2.getChildAdapterPosition(v);
photo_item2 item = mAdapter2.getDataSet().get(position);
final String key = item.getMatchId();
}
});
mAdapter2.floatingActionButtonView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = mRecyclerView2.getChildAdapterPosition(v);
photo_item2 item = mAdapter2.getDataSet().get(position);
final String key = item.getMatchId();
}
});
mAdapter2.floatingActionButtonChat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = mRecyclerView2.getChildAdapterPosition(v);
photo_item2 item = mAdapter2.getDataSet().get(position);
final String key = item.getMatchId();
}
});
I get the following error when I move to the fragment:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.material.floatingactionbutton.FloatingActionButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.firetest.Tabs.MatchProcess.MatchFragment.onCreateView
Adapter:
public class photo_adapter2 extends RecyclerView.Adapter<photo_adapter2.ViewHolder> {
ImageView imageView;
FloatingActionButton floatingActionButtonDelete;
FloatingActionButton floatingActionButtonChat;
FloatingActionButton floatingActionButtonView;
private Uri imageUri;
private ArrayList<photo_item2> mDataSet;
private Context mContext;
private OnItemClickListener mListener;
public ArrayList<photo_item2> getDataSet() {
return mDataSet;
}
public void setDataSet(ArrayList<photo_item2> mDataSet) {
this.mDataSet = mDataSet;
}
public ImageView getImageView() {
return imageView;
}
public void setImageView(ImageView imageView) {
this.imageView = imageView;
}
public Context getContext() {
return mContext;
}
public void setContext(Context mContext) {
this.mContext = mContext;
}
public Uri getImageUri() {
return imageUri;
}
public void setImageUri(Uri imageUri) {
this.imageUri = imageUri;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public photo_adapter2(Context context, ArrayList<photo_item2> DataSet) {
mDataSet = DataSet;
mContext = context;
}
public ArrayList<photo_item2> DataSet() {
return mDataSet;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public FloatingActionButton floatingActionButtonDelete;
public FloatingActionButton floatingActionButtonView;
public FloatingActionButton floatingActionButtonChat;
public RelativeLayout mLinearLayout;
private int adapterPositionOnCLick;
public ViewHolder(View v, final OnItemClickListener listener) {
super(v);
mImageView = (ImageView) v.findViewById(R.id.tv);
floatingActionButtonDelete = (FloatingActionButton) v.findViewById(R.id.floatingActionButtonDelete);
floatingActionButtonChat = (FloatingActionButton) v.findViewById(R.id.floatingActionButtonChat);
floatingActionButtonView = (FloatingActionButton) v.findViewById(R.id.floatingActionButtonView);
floatingActionButtonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null) {
adapterPositionOnCLick = getAdapterPosition();
if (adapterPositionOnCLick != RecyclerView.NO_POSITION) ;
listener.onItemClick(adapterPositionOnCLick);
}
}
});
floatingActionButtonChat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null) {
adapterPositionOnCLick = getAdapterPosition();
if (adapterPositionOnCLick != RecyclerView.NO_POSITION) ;
listener.onItemClick(adapterPositionOnCLick);
}
}
});
floatingActionButtonView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null) {
adapterPositionOnCLick = getAdapterPosition();
if (adapterPositionOnCLick != RecyclerView.NO_POSITION) ;
listener.onItemClick(adapterPositionOnCLick);
}
}
});
mLinearLayout = (RelativeLayout) v.findViewById(R.id.ll);
}
public ImageView getImageView() {
return mImageView;
}
public void setImageView(ImageView mImageView) {
this.mImageView = mImageView;
}
}
#Override
public photo_adapter2.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.photo_custom_view_card, parent, false);
ViewHolder vh = new ViewHolder(v, (OnItemClickListener) mListener);
return vh;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final photo_item2 photo_item = mDataSet.get(position);
}
#Override
public int getItemCount() {
return mDataSet.size();
}
}
How would I go about creating three onClickListeners like this? How should I modify my current fragment and adapter set up to achieve that? Please let me know if there is anything else I should add to my post.
I think, you can create an interface onFabClickListener to dispatch the original onClick event on the FloatingActionButton to your Activity or Fragment. If three FloatingActionButtons are only way to interact with the row of RecyclerView, then I guess you don't even need to handle onItemClick()(or one which handle onclick of row overall).
The interface onFabClickListener.java may look like this :
// is supposed to handle every fab click of every viewholder
public interface OnFabClickListener {
// view to know which fab was click and position to know the position
// of viewholder that was clicked
void onFabClick(View view, int position);
}
Then your Adapter class may look like this :
public class photo_adapter2 extends RecyclerView.Adapter<photo_adapter2.ViewHolder> {
// you all other variable declarations
private ArrayList<photo_item2> mDataSet;
private Context mContext;
private OnFabClickListener mListener;
// your all other required methods definition
public void setOnFabClickListener(OnFabClickListener listener) {
mListener = listener;
}
public ArrayList<photo_item2> getDataSet() {
return mDataSet;
}
public void setDataSet(ArrayList<photo_item2> mDataSet) {
this.mDataSet = mDataSet;
}
public photo_adapter2(Context context) {
mContext = context;
}
#NonNull
#Override
public photo_adapter2.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.photo_custom_view_card, parent, false);
return new ViewHolder(v, mListener);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
final photo_item2 photo_item = mDataSet.get(position);
// do you stuff here
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private OnFabClickListener listener;
public ViewHolder(View v, final OnFabClickListener listener) {
super(v);
// your all other view initialization
//setting our listener object
this.listener = listener;
// your all other views declaration
FloatingActionButton floatingActionButtonDelete = v.findViewById(R.id.floatingActionButtonDelete);
FloatingActionButton floatingActionButtonChat = v.findViewById(R.id.floatingActionButtonChat);
FloatingActionButton floatingActionButtonView = v.findViewById(R.id.floatingActionButtonView);
// setting onclicklisteners on them
// our view holder class is gonna handle all of the onclick
floatingActionButtonDelete.setOnClickListener(this);
floatingActionButtonChat.setOnClickListener(this);
floatingActionButtonView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
// if the view is a floating action button and listener is not equal to null
if (view instanceof FloatingActionButton && listener != null) {
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
// for every on click listened here we will dispatch it to our activity or fragment which
// is required to respond to those events
listener.onFabClick(view, getAdapterPosition());
}
}
}
// your all other methods definition
}
}
Then now a sample MainActivity which implements our custom onFabClickListener will receive the appropriate onclick events handled and dispatched initially by our photo_adapter2 class may look like this:
public class MainActivity extends AppCompatActivity implements OnFabClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// declare and initialize the recyclerview
RecyclerView rcView = ......
// declare and initialize the requiredadapter
photo_adapter2 adapter = .....
// set the data using setDataSet() or you can skip this if you
// already passed the dataset in the constructor
adapter.setDataSet(yourDataSet);
// set this class as the onFabClickListener(you forgot this one I guess)
adapter.setOnFabClickListener(this);
// set the adapter to the recyclerview
rcView.setAdapter(adapter);
}
#Override
public void onFabClick(View view, int position) {
int id = view.getId();
switch (id) {
case R.id.floatingActionButtonDelete:
// you can now do your stuff here
break;
case R.id.floatingActionButtonChat:
// for eg get the item associated with the viewholder of whose fab was clicked
photo_item2 item = mAdapter2.getDataSet().get(position);
break;
case R.id.floatingActionButtonView:
break;
}
}
}
Note:
According to Material Design Specifications, it is not recommended to use more than one FloatingActionButton in the single screen(Activity/Fragment). It represents the most important single frequent action that is performed by the user. Instead, I think you should switch to MaterialButton and if you are using Fab just to get this circular look, you need to switch immediately. You can specify the materialButtonStyle attribute in your styles.xml file to get a circular look.
Check your XML file where all three floating action buttons are created, make sure you have them all created, with the respective names that you accessing from the view. The NullPointerException is telling you that one of your floating action button's are pointed to something that doesn't yet exist.
i have recycler adapter like this
public class ShopUsersAdapter extends RecyclerView.Adapter<ShopUsersAdapter.MyViewHolder> implements View.OnClickListener {
private List<ShopUsersRecyclerModel> user_list;
private Context context;
private AdminCheckLocActivity activity;
private AdapterCallback mAdapterCallback;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView user;
public TextView type;
private ImageButton btn_loc;
public MyViewHolder(View view) {
super(view);
user = (TextView) view.findViewById(R.id.txt_text);
type =(TextView)view.findViewById(R.id.txt_count);
btn_loc=(ImageButton)view.findViewById(R.id.btn_loc);
}
}
#Override
public ShopUsersAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.map_pop_up_item, parent, false);
context=parent.getContext();
itemView.setOnClickListener(this);
return new ShopUsersAdapter.MyViewHolder(itemView);
}
#Override
public void onClick(View v) {
}
public ShopUsersAdapter(List<ShopUsersRecyclerModel> user_list, AdminCheckLocActivity activity) {
this.user_list = user_list;
this.activity=activity;
this.mAdapterCallback = ((AdapterCallback) context);
}
#Override
public void onBindViewHolder(final ShopUsersAdapter.MyViewHolder holder, int position) {
final ShopUsersRecyclerModel user = user_list.get(position);
holder.user.setText(user.getUser_info());
if (user.getUser_type()==3){holder.type.setText("TV Pro.");}
if (user.getUser_type()==4){holder.type.setText("B. Esya Pro.");}
holder.btn_loc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAdapterCallback.onMethodCallback(user.getUser_info());
}
});
}
#Override
public int getItemCount() {
return user_list.size();
}
public interface AdapterCallback {
void onMethodCallback(String userName);
}
}
but i get error
NullPointer at
mAdapterCallback.onMethodCallback(user.getUser_info());
my activity code;
#Override
public void onMethodCallback(final String userName) {
Toast.makeText(this,userName,Toast.LENGTH_LONG).show();
}
and i implement this like ;
implements ShopUsersAdapter.AdapterCallback
userInfo data is not null, i check this. but i need this callback all of my recyclers please help me.
I suggest changing your adapter's constructor to directly receive a callback:
public ShopUsersAdapter(List<ShopUsersRecyclerModel> user_list, AdminCheckLocActivity activity, AdapterCallback callback) {
this.user_list = user_list;
this.activity=activity;
this.mAdapterCallback = callback;
}
You can also make sure your callback isn't null when you're utilizing it:
holder.btn_loc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This should be optional for your case
// but it can be useful if you're ever in a situation
// where the callback isn't always available
if(mAdapterCallback != null){
mAdapterCallback.onMethodCallback(user.getUser_info());
}
}
});
And within your Activity, make sure to pass in the callback as an argument when you create your Adapter instance:
// Use 'this' since your Activity implements the callback
ShopUsersAdapter adapter = new ShopUsersAdapter(myList, myActivity, this);
I have a setOnClick listener inside my onBindViewHolder
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
((ViewHolder) holder).txtType.setText(object.text);
((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();
//???.scrolltoPosition(position+1);
}
});
on click, I would be scrolling the viewport to the next recycler view item. I've done this inside my MainActivity java by recyclerView.scrollToPosition(position);. But inside Adapter Class on onBindViewHolder, I have no idea how to call my recyclerView on the Main Java Class.
How should I do this?
edit:
For simplification purposes, I revised this previous code, because I have used a multiview adapter for my recycler. Here is the multiview adapter:
public class MultiViewTypeAdapter extends RecyclerView.Adapter {
private ArrayList<InstructionModel>dataSet;
Context mContext;
int total_types;
private LinearLayoutManager manager;
public MultiViewTypeAdapter(LinearLayoutManager manager)
{
this.manager=manager;
}
public static class SimpleTextViewHolder extends RecyclerView.ViewHolder {
TextView txtType;
CardView cardView;
CheckBox checkBox;
public SimpleTextViewHolder(View itemView) {
super(itemView);
this.txtType = (TextView) itemView.findViewById(R.id.type);
this.cardView = (CardView) itemView.findViewById(R.id.card_view);
this.checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
}
public static class TimeTextViewHolder extends RecyclerView.ViewHolder {
TextView txtType;
CardView cardView;
CheckBox checkBox;
public TimeTextViewHolder(View itemView) {
super(itemView);
this.txtType = (TextView) itemView.findViewById(R.id.type);
this.cardView = (CardView) itemView.findViewById(R.id.card_view);
this.checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
}
public MultiViewTypeAdapter(ArrayList<InstructionModel> data, Context context) {
this.dataSet = data;
this.mContext = context;
total_types = dataSet.size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case InstructionModel.SIMPLE_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.simple, parent, false);
return new SimpleTextViewHolder(view);
case InstructionModel.TIME_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.time, parent, false);
return new TimeTextViewHolder(view);
}
return null;
}
#Override
public int getItemViewType(int position) {
switch (dataSet.get(position).type) {
case 0:
return InstructionModel.SIMPLE_TYPE;
case 1:
return InstructionModel.TIME_TYPE;
default: return -1;
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int listPosition) {
InstructionModel object = dataSet.get(listPosition);
if (object != null) {
switch (object.type) {
case InstructionModel.SIMPLE_TYPE:
((SimpleTextViewHolder) holder).txtType.setText(object.text);
break;
case InstructionModel.TIME_TYPE:
((TimeTextViewHolder) holder).txtType.setText(object.text);
break;
}
}
}
#Override
public int getItemCount() {
return dataSet.size();
}
P.S.
If you see some random useless stuff, I was trying something.
Pass the LayoutManger with constuctor
class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private LinearLayoutManager manager;
public Adapter(LinearLayoutManager manager)
{
this.manager=manager;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
((ViewHolder) holder).txtType.setText(object.text);
((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();
manager.scrollToPosition(position+1);
}
});
}
I think you should define a interface to notify your parent RecyclerView to do scroll operation, the RecyclerView into ViewHodler inside operation, resulting in the coupling
You can pass a listener object in the constructor which implements by Fragment OR Activity.
/**
* item click interface of adapter
*/
public interface MultiViewTypeAdapterListener {
void onScroll(int position)
}
This interface implements by Fragment OR Activity
/**
* On Scroll Implement Method from adapter listener.
*
* #param position
*/
#Override
public void onScroll(int position) {
// Here you can call that method
recyclerview.scrolltoPosition(position)
}
Then you pass this listener in the constructor of the adapter.
private void buildRecyclerView() {
multiViewTypeAdapter = new MultiViewTypeAdapter(this);
recyclerView.setAdapter(multiViewTypeAdapter);
}
In the constructor, you can assign like this
private MultiViewTypeAdapterListener mMultiViewTypeAdapterListener;
public OfferAdapter(MultiViewTypeAdapterListener mMultiViewTypeAdapterListener) {
this.mMultiViewTypeAdapterListener = mMultiViewTypeAdapterListener
}
}
Now you can use this listener by setting click listener on anyViwe like this
((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();
//???.scrolltoPosition(position+1);
mMultiViewTypeAdapterListener.onScroll(position+1);
}
});
It returns to call the method of onItemClick which implements this method.
private int getScrollRange() {
int scrollRange = 0;
if (parent.getChildCount() > 0) {
View child = parent.getChildAt(0);
scrollRange = Math.max(0,
child.getHeight() - (parent.getHeight()));
}
return scrollRange;
}
ScrollView parent=findViewById(R.id.scroll_Recipe_Detail);
parent.scrollTo(0,getScrollRange());
if you want to scroll on new items added, you must override "onItemsAdded".
Here is how I did it:
recyclerView.apply {
setHasFixedSize(true)
layoutManager = MyLinearLayoutManager(this#MainActivity)
...
}
private class MyLinearLayoutManager(private val context: Context) :
LinearLayoutManager(context) {
// Force new items appear at the top
override fun onItemsAdded(recyclerView: RecyclerView, positionStart: Int, itemCount: Int) {
super.onItemsAdded(recyclerView, positionStart, itemCount)
scrollToPosition(findLastVisibleItemPosition())
}
}
I need to pass data from recyclerView adapter to main activity on click on image of recyclerview. Can someone help?
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder> {
private ArrayList<Video> mData;
private ArrayList<Video> mData2;
private Activity mACtivity;
public VideoAdapter(ArrayList<Video> data, ArrayList<Video> data2, Activity activity) {
this.mData = data;
this.mData2 = data2;
this.mACtivity = activity;
}
#Override
public VideoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.anteprima_list_item, parent, false);
//view.setOnClickListener(mOnClickListener);
return new VideoHolder(view);
}
#Override
public void onBindViewHolder(VideoHolder holder, int position) {
Video video = mData.get(position);
final Video video2 = mData2.get(position);
holder.setTitolo(video.getTitolo());
holder.setSottoTitolo(video.getSottotitolo());
holder.setData(video.getData());
holder.setData(video.getData());
/* holder.setAddress(restaurant.getAddress());
holder.setCost("Average cost for 2: " + restaurant.getCurrency() + restaurant.getCost());
holder.setRating(restaurant.getRating());*/
Glide.with(mACtivity)
.load(video2.getPic())
.into(holder.restaurantImageView);
holder.restaurantImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// handle click event here
System.out.println("PIC"+video2.getPic());
}
});
}
#Override
public int getItemCount() {
if (mData == null)
return 0;
return mData.size();
}
public class VideoHolder extends RecyclerView.ViewHolder {
ImageView restaurantImageView;
TextView restaurantNameTextView;
TextView restaurantAddressTextView;
TextView restaurantRatingTextView;
TextView costTextView;
TextView distanceTextView;
LinearLayout linearlayout;
public VideoHolder(View itemView) {
super(itemView);
linearlayout=(LinearLayout) itemView.findViewById((R.id.linearlayout));
restaurantImageView = (ImageView) itemView.findViewById(R.id.imageview_restaurant);
restaurantNameTextView = (TextView) itemView.findViewById(R.id.textview_restaurant_name);
restaurantAddressTextView = (TextView) itemView.findViewById(R.id.restaurant_address_textview);
distanceTextView = (TextView) itemView.findViewById(R.id.restaurant_distance_textview);
/* costTextView = (TextView) itemView.findViewById(R.id.cost_for_two_textview);
restaurantRatingTextView = (TextView) itemView.findViewById(R.id.rating);*/
}
public void setTitolo(String titolo) {
restaurantNameTextView.setText(titolo);
}
public void setSottoTitolo(String sottotitolo) {
restaurantAddressTextView.setText(sottotitolo);
}
public void setData(String data) {
distanceTextView.setText(data);
}
/* public void setPic(String pic) {
distanceTextView.setText(pic);
}
public void setCost(String cost) {
costTextView.setText(cost);
}
public void setDistance(String distance) {
distanceTextView.setText(distance);
}*/
}
}
Create a listener Interface and let your MainActivity implement it. That way you can call your callback method in your onClick method.
Interface:
public interface OnImageClickListener {
void onImageClick(String imageData);
}
MainActivity:
public class MainActivity implements OnImageClickListener {
#Override
public void onImageClick(String imageData) {
// handle image data
}
//...
}
Your VideoAdapter:
//...
private OnImageClickListener onImageClickListener;
public VideoAdapter(ArrayList<Video> data, ArrayList<Video> data2, Activity activity, OnImageClickListener onImageClickListener) {
this.mData = data;
this.mData2 = data2;
this.mACtivity = activity;
this.onImageClickListener = onImageClickListener;
}
//...
#Override
public void onBindViewHolder(VideoHolder holder, int position) {
//...
holder.restaurantImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onImageClickListener.onImageClick(video2.getPic());
}
});
//...
}
//...
If you want to pass value from onclick to your Parent activity, use onMethodCallback in your MainActivity:
public class MainActivity extends Activity implements AdapterCallback {
private MyAdapter mMyAdapter;
#Override
public void onMethodCallback(String yourValue) {
// get your value here
}
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mMyAdapter = new MyAdapter(this);
}
}
In your Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private AdapterCallback mAdapterCallback;
public MyAdapter(Context context) {
try {
this.mAdapterCallback = ((AdapterCallback) context);
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement AdapterCallback.");
}
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
// simple example, call interface here
// not complete
viewHolder.itemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mAdapterCallback.onMethodCallback();
}
});
}
public static interface AdapterCallback {
void onMethodCallback(String yourValue);
}
}
If you are working with kotlin, the solution is much simpler.
Original Answer here
pass the lamda val itemClick: (Int) -> Unit to your adapter.
class MyRecyclerViewAdapter(params , val itemClick: (Int) -> Unit): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
internal inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
...
itemView.setOnClickListener( {itemClick(layoutPosition)} )
}
}
In your Activity use the returned value position
val myAdapter = MyRecyclerViewAdapter(params) { position ->
// do something
}
Write interface in your adapter like bellow :
interface clickItemListener {
void onItemClick(String order);
}
And your constructor should be :
privat clickItemListener clickItemListeners;
public VideoAdapter(ArrayList<Video> data, ArrayList<Video> data2, Activity activity, clickItemListener clickItemListeners) {
this.mData = data;
this.mData2 = data2;
this.mACtivity = activity;
this.clickItemListeners = clickItemListeners;
}
Then you can pass to Activity :
yourLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
clickItemListeners.onItemClick(yourValue);
}
});
And implement your interface in your activity like bellow :
public class yourActivity extends AppCompatActivity implements
YourAdapter.clickItemListener{
#Override
public void onItemClick(String order) {
//You can get your value here
}
}
Remember that you should pass activity to adapter like bellow :
YourAdapter adapter = new YourAdapter (... , ... , ... , activity.this);