Using Otto Event Bus to pass data between RecyclerViews - android

I have 2 Recyclerviews inside 2 different Fragments contained in a ViewPager. When a card in my RecyclerviewA is clicked I would like to pass the respective object over to RecyclerviewB currently I have an onClick in RecyclerView with the following code:
#Override
public void onBindViewHolder(ViewHold holder, int position) {
holder.nameTextView.setText(list.get(position).getString("name"));
holder.addressTextView.setText(list.get(position).getString("fromAddress"));
final int pos = position;
holder.acceptButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ApplicationClass.bus.post(list.get(pos));
}
});
In RecyclerViewB I have
public PickupListAdapter(Context context, List<ParseObject> ddList) {
this.ddList = ddList;
this.mContext = context;
ApplicationClass.bus.register(mContext);
}
#Subscribe
public void answerAvailable(ParseObject object) {
ddList.add(object);
notifyDataSetChanged();
}
Inside my Application Class I have:
public static Bus bus;
#Override
public void onCreate(){
super.onCreate();
bus = new Bus(ThreadEnforcer.MAIN);
}
The "answerAvailable" method is not called. What is currently incorrect regarding my implementation?

I can see only one change from my working code. Can you try changing this:
bus= new Bus(ThreadEnforcer.ANY);

Related

Passing key to next activity

I'm developing an application with the MVP architecture. I have a RecyclerView with the following method:
#Override
public void onBindViewHolder(#NonNull ChatRoomAdapter.ChatRoomViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mChatRooms.get(position).getUid();
}
});
}
I need to pass the mChatRooms.get(position).getUid() to the next acitivty/presenter/interactor but how can I cleanly do this? Can I use an intent using the putExtra method to pass the data?
You must do something like
interface YourPresenter {
void onItemClicked(int uid);
}
class YourPresenterImpl : YourPresenter {
#Override
void onItemClicked(int uid) {
view.startActivity(uid) // method from your interface for you view
}
}
and then you must add your presenter's reference to you item click in holder

RecyclerView Adapter onBind method

I have in my MainActivity 3 RecyclerViews .
One of them in a bottom sheet and it is the main one (By Default the Bottom sheet is Open To Display this one ), in its adapter's onbind method I made an onClickListener so that I want when the user clicks on an item in it,
I want to go back to the main activity class to set To Start a method which it's rolled is to close the Bottom Sheet and set the data for the next recycling view (which will appear when the Bottom Sheet is closed)
..... The issue here is how to start this method from the onBind method's Listener and give it a parameter from this viewHolder as its name and some of its attributes
if there is something not clear please let me know
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
viewHolder.categoryImage.setImageResource(mRowOfCategories.get(position).getCategoryImage());
viewHolder.categoryName.setText(mRowOfCategories.get(position).getCategoryName());
viewHolder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
Easiest:
You declare the method you want to call in your Activity. It has to be public:
public void method(){}
Then, in the Constructor of the Adapter, you pass a reference to the Activity as a parameter:
public MyAdapter(Activity activity){}
And, in the onBindViewHolder:
MyActivity mActivity=(MyActivity)activity;
mActivity.method();
You can do that easily.
Define custom interface
public Interface CustomEventListener
{
public void MyEventListener(String message); //you can change parameters
}
In your adapter class
public Adapter ......... {
private CustomEventListener listener;
public void setListener(CustomEventListener listener)
{
this.listener = listener;
}
//Your onBind
Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
viewHolder.categoryImage.setImageResource(mRowOfCategories.get(position).getCategoryImage());
viewHolder.categoryName.setText(mRowOfCategories.get(position).getCategoryName());
viewHolder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.MyEventListener("Message");
}
});
}
}
In your Activity when create Adapter add this code
public void InitAdapter()
{
yourAdapter = new Adapter(); // bloa bla bla
yourAdapter.setListener(new CustomEventListener() {
public void MyEventListener(String message)
{
// then do what you want
}
}
}
You need to use Listener for handling the click in your Adapter something like this:
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
then call the listener with:
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
...
viewHolder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// call the listener.
mListener.onItemClick(v, viewHolder.getAdapterPosition());
}
});
}
then when you're using the adapter, set the listener with something like this:
adapter.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(View view, int position) {
// do something with the view and position.
}
});
You want your recycleviews to be aware of each other. You'll need a class, maybe MainActivity, that will keep the selected value, also clear it upon request, in between recycleviews. Then you'll need that value to propagate the next recycleview. If you want to be efficient then you'll use one recycleview and swap the data in between selections, and animate it so it looks like a new recycleview is created.

Calling Fragment method from attached RecyclerView.Adapter

I recently started coding my first Android project using Android Studio 3.1.2 and SDK 19.
One of my fragments contains a RecyclerView with a custom RecyclerView.Adapter attached. On the CardView the Adapter gets by its ViewHolder, there can be a button. The target is, if the button is pressed, a method of my fragment should be called, though it's an instance of a custom subclass of Fragment:
From RequestingFragment:
public abstract class RequestingFragment extends Fragment implements RequestCallbacks {
public final static void startRequest(final RequestOperation, String param) {
//this is the guy i want to call
}
//these are the RequestCallbacks, they're all getting called in startRequest()
public void onSuccess(JSONObject json, String parsingkey) { }
public void onError() { }
public void onFinished() { }
Now one of my RequestingFragments contains a RecyclerView, on which a custom ErrorCompactAdapter is attached. Inside the Adapters ViewHolder, where I load the layout for the single CardViews, there's a button, which should call startRequest() onClick from my RequestingFragment
From ErrorCompactAdapter:
public class ErrorCompactAdapter extends RecyclerView.Adapter<ErrorCompactAdapter.ErrorCompactViewHolder> {
private Context context;
private ArrayList<Error> errors;
public ErrorCompactAdapter(Context context, ArrayList<Error> errors) {
this.context = context;
this.errors = errors;
}
public void onBindViewHolder(ErrorCompactViewHolder, int position) {
//...
holder.errorTakeOverButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//here's were i'm stuck
}
});
//...
}
}
My first approach was to change the context attribute of ErrorCompactAdapter to a RequestingFragment, so that I can call startRequest() on this.
private Context context; // private RequestingFragment attacher;
public void onClick(View v) {
attacher.startRequest(/*params*/);
}
But i'm very unsure, if the fragment that contains the RecyclerView will be the one which receives the response of the request, or if a somehow "pseudo-anonymous" Fragment will receive the response and simply does nothing with it then. Can someone enlight me, if this is the correct path? Thanks in advance.
Pass the Fragment in you ErrorCompactAdapter class's constructor. This works for me the way I want. I had the same issue.
RequestingFragment mFragment;
public ErrorCompactAdapter(Context context, ArrayList<Error> errors,
RequestingFragment fragment)
{
this.context = context;
this.errors = errors;
this.mFragment = fragment;
}
// While passing the fragment into your adapter, do it this way.
ErrorCompactAdapter errorCompactAdapter = new ErrorCompactAdapter(
context, errors, RequestingFragment.this);
holder.errorTakeOverButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// use you method of fragment here
mFragment.startRequest();
}
});

How to get the List size() from adapter and update Activity UI from recycler Adapter itself?

I have a delete button in my adapter call and when i press the delete button i want to
1. remove the value from list and,
2. Update the size of the list in the main activity
and . Have tried using Interface where i referred here but it's not working and i am so confused.
So can any one provide me an best way
My Adapter Code:
#Override
public void onBindViewHolder(final AddLineItem_Adapter.ViewHolder holder, final int position) {
final AddLineItem_ListView addLineItem_listView = addLineItem_listViews.get(position);
holder.tv_OrderID.setText(addLineItem_listView.getItemID());
holder.tv_ProductName.setText(addLineItem_listView.getProductName());
holder.tv_Quantity.setText(addLineItem_listView.getQuantity());
holder.tv_UnitPrice.setText(addLineItem_listView.getUnitPrice());
holder.tv_TotalAmount.setText(addLineItem_listView.getTotalAmount());
holder.btn_Delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addLineItem_listViews.remove(position);
notifyDataSetChanged();
}
});
}
I want to update the addLineItem_listView size on the main activity in TextView.
Create the interface..
Pass it to the adapter..
Call interface function after deleting (providing the size of list)
Create interface
public interface ShowDeleted {
void showDeleted(int size);
}
Initialize the interface anonymously in the activity like this
ShowDeleted showDeleted = new ShowDeleted() {
#Override
public void showDeleted(int size) {
// show the changed list size or update UI
}
};
Pass the interface to the recyclerAdapter
YourAdapter youradpter = new YourAdpater(context,list,showDeleted );
Initialize the constructor of recyclerAdapter like this:-
public YourAdapter(Context context, YourList yourList, ShowDeleted
showDeleted)
{
}
holder.onClick do this
holder.btn_Delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addLineItem_listViews.remove(position);
notifyDataSetChanged();
this.showDeleted.showDeleted(addLineItem_listViews.size());
}
});
try to use view.setTag(position)
#Override
public void onBindViewHolder(final AddLineItem_Adapter.ViewHolder holder, final int position) {
final AddLineItem_ListView addLineItem_listView = addLineItem_listViews.get(position);
holder.tv_OrderID.setText(addLineItem_listView.getItemID());
holder.tv_ProductName.setText(addLineItem_listView.getProductName());
holder.tv_Quantity.setText(addLineItem_listView.getQuantity());
holder.tv_UnitPrice.setText(addLineItem_listView.getUnitPrice());
holder.tv_TotalAmount.setText(addLineItem_listView.getTotalAmount());
holder.btn_Delete.setTag(position)
holder.btn_Delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addLineItem_listViews.remove((Integer)v.getTag());
notifyDataSetChanged();
}
});
}
Good Luck!
use this function
public void removeAt(int position) {
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, list.size());
}

A onSwiped() in the recyclerView within fragment to send back the info to the MainActivity?

I need some help setting up a listener in the MainActivity waiting for a recyclerview item to be swiped off.
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
Log.d(TAG, "whats swiped " + viewHolder.getAdapterPosition() + " direction: " + direction + " arrayListCountyNames.get(viewHolder.getAdapterPosition())" + arrayListCountyNames.get(viewHolder.getAdapterPosition()));
final String s = arrayListCountyNames.get(viewHolder.getAdapterPosition());
final String s2 = arrayListStateName.get(viewHolder.getAdapterPosition());
final String s3 = arrayListSourceId.get(viewHolder.getAdapterPosition());
final String s4 = arrayListID.get(viewHolder.getAdapterPosition());
I need to get back to the MainActivity because that`s where everything is executed.
There are two ways of sending your data to other classes.
First one is using your own call back methods as this.
First create a model class to store the data you need to send Example:
public class Details {
public String s ;
public String s2 ;
public String s3;
public String s4;
}
Then create a Listener(interface) in your fragment as below:
public class BlankFragment extends Fragment {
private OnSwipeMyRecyclerViewListener mListener;
public BlankFragment() {
// Required empty public constructor
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnSwipeMyRecyclerViewListener) {
mListener = (OnSwipeMyRecyclerViewListener) context;
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnSwipeMyRecyclerViewListener{
void onSwipeMyRecyclerView(Details details, int position);
}
}
After that in your onSwiped method, create an object of your details class and assigned all the values you need to pass and call the listener as below:
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//your code
Details details = new Details();
details.s = s;
details.s2 = s2;
details.s3 = s3;
details.s4 = s4;
mListener.onSwipeMyRecyclerView(details,direction);
}
and finally implement your listener in your Activity as below.
public class MainActivity extends AppCompatActivity implements BlankFragment.OnSwipeMyRecyclerViewListener {
#Override
public void onSwipeMyRecyclerView(Details details, int position) {
//Do whatever want to do with your data here
}
}
Or Second one is easy. You have to use a third party library like EventBus https://github.com/greenrobot/EventBus or Otto http://square.github.io/otto/ follow above links.
Now try and let us know... :)

Categories

Resources