Android RecyclerView onClick with JSON - android

I want to transfer to another fragment the item that I clicked on my recyclerview. I don't know how to transfer the data that I clicked on my recyclerview to another fragment. Here's my code. The data is from my JSON.
public void onBindViewHolder(ViewHolder holder, int position) {
final ListItem listItem = listItems.get(position);
holder.textViewHead.setText(listItem.getHead());
holder.textViewDesc.setText(listItem.getDesc());
Picasso.with(context)
.load(listItem.getImgUrl())
.into(holder.imageViewElliptic);
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "You clicked " + listItem.getHead(), Toast.LENGTH_LONG).show();
}
});
}

Well, first you should store your data either in a List or some other accessible data object, and I think you are doing that already since you created your adapter.
Well, you have this line:
public void onBindViewHolder(ViewHolder holder, int position) {
You can get the data from your List or something else by using the position provided by the method, like this:
YourJsonData data = yourDataSource.get(holder.getAdapterPosition());
Since you are using an onClickListener you should not call position directly, this might cause issues.
For example, in my project I use Lesson[] as my data source:
https://github.com/gi097/MyWindesheim/blob/master/app/src/main/java/com/giovanniterlingen/windesheim/view/Adapters/ScheduleAdapter.java
Once you get the data you can Intent a new Activity which creates the fragments for you. Alternatively, if there is already a Fragment present, you can update that one by notifying your Activity which then updates that particular Fragment.

Use Intent in onClick and send the whole ArrayList to the next activity
Intent intent = new Intent(context, AnotherActivity.class);
intent.putExtra("model", arrayList.get(position));
context.startActivity(intent);
And receive it in next Activity by using this code snippet.
Intent i = getIntent();
ArrayModel arrayModel = (ArrayModel) i.getSerializableExtra("model");
if (arrayModel != null) {
String head = arrayModel.getHead();
Log.d("HEAD", head);
}

Related

ViewModel method does not call every time onCreate method is called

My application fetches data from API and populates the recycler view with food's categories image and name. When I click on any image then another activity will open and the second activity will show a list of food of that category. But when I open any category then it's working for the first time but if I press back or Up button came back to the MainAcivity and tap on any other Category then the food items on the Second activity is not changing(ViewModel's method is not getting called).
See the Full Code on GitHub: https://github.com/harshabhadra/Foodie/tree/master/app/src/main
This is MainAcivity's onClick method. I am sending the category name via Intent:
#Override
public void onItemClick(int item) {
Intent categoryIntent = new Intent(MainActivity.this,
CategoryActivity.class);
categoryIntent.putExtra("name", foodAdapter.getFood(item));
startActivity(categoryIntent);
}
This is my second Activity:
Intent intent = getIntent();
Food food = intent.getParcelableExtra("name");
category = food.getFoodName();
setTitle(category);
foodViewModel = ViewModelProviders.of(this).get(FoodViewModel.class);
foodViewModel.getFoodCategory(category).observe(this, new
Observer<List<FoodCategory>>() {
#Override
public void onChanged(List<FoodCategory> foodCategories) {
if (!foodCategories.isEmpty()) {
progressBar.setVisibility(View.GONE);
categoryAdapter = new
CategoryAdapter(CategoryActivity.this, foodCategories);
recyclerView.setAdapter(categoryAdapter);
Log.e(TAG, "Category Name: " + category);
}else {
Toast.makeText(CategoryActivity.this, "empty list",
Toast.LENGTH_SHORT).show();
}
}
});
I'm expecting to see a different list of foods in the Second Activity according to the category when I tap on that category in MainAcivity.
What's happening is that you are calling loadData(category) in your repository when categoryData is null, i.e. the first time it runs. Afterwards it returns the same livedata without loading on the new category data.
You just need to move loadData outside the if. Or what you could actually do is to initialize lazily categoryData and get rid of the if.

Passing data from one activity to interactor of another activity

I'm developing a chat application. There are chatrooms and inside these rooms there are messages. When a user clicks on the chatroom I want to go to another activity where messages are displayed.
In my adapter class, I have this onclick() method written in onBindViewHolder where I would normally make an intent along with the data I need. Something like this:
#Override
public void onBindViewHolder(#NonNull ChatRoomAdapter.ChatRoomViewHolder holder, final int position) {
holder.mRoomTitle.setText(mChatRooms.get(position).getTitle());
holder.mRoomDescription.setText(mChatRooms.get(position).getDescription());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(this, NextActivity.java);
intent.putExtra("test", mChatRooms.get(position).getTitle());
}
});
}
But I'm trying the MVP architecture design and I want to pass roomTitle to the Interactor/presenter class of my next activity. How can I achieve this?
In RecyclerView adapter you need to pass a onItemClickListener in the adapter.
Refer to the Google's MVP sample - > https://github.com/googlesamples/android-architecture/tree/todo-mvp/
Especially refer the TaskItemListener in TaskFragment. They are doing the same thing what you are trying to achieve. In this they open Task details (new activity) from List of tasks(recyclervView).
/**
* Listener for clicks on tasks in the ListView.
*/
TaskItemListener mItemListener = new TaskItemListener() {
#Override
public void onTaskClick(Task clickedTask) {
mPresenter.openTaskDetails(clickedTask);
}
#Override
public void onCompleteTaskClick(Task completedTask) {
mPresenter.completeTask(completedTask);
}
#Override
public void onActivateTaskClick(Task activatedTask) {
mPresenter.activateTask(activatedTask);
}
};
And then pass it to adapter of Recycler view
mListAdapter = new TasksAdapter(new ArrayList<Task>(0), mItemListener);
And on item click
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemListener.onTaskClick(task);
}
});
Follow this article to know more about MVP.
You can do one thing that creates a method in the next activity's presenter
setRoomTitle(String roomTitle);
Whenever, you click and send intent and get in next Activity call that
mPresenter.setRoomTitle(roomTitle);
Is it make sense? So, you can sent your title or other data in next activity's presenter.
Let me know if you have more query then.
Thanks.
Happy coding :)
The adapter is only responsible for binding the view and the data together. Your business logic should go into the controller class which is your Activity or Fragment containing the RecyclerView. This way you can reuse it for any other Activity, and it also makes debugging/maintaining a lot easier since you know that your logic code is in one place.
But how do you link both together? It's simply done by implementing a callback interface and passing it to your adapter. A callback interface could be something like this:
interface OnClickCallback{
void onClick(String title);
}
Just add a member variable to your adapter class called mCallback for example and affect a reference to it through the adapter constructor or through a setter method.
You can either make your Activity implement this interface and pass itself as the reference or you can instantiate it in an object and pass it instead.
Then just write this:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onClick(mChatRooms.get(position).getTitle());
}
});
The onClick method should create an intent to your new Activity with an extra containing the title. In your new Activity's onCreate method, you can retrieve the title value by using:
String title = getIntent().getStringExtra(YOUR_TITLE_KEY_HERE);

delete item from Activity after receive it in Fragment / Lifecycle issue

I need some help. I've got activity where I create item. Next I want to send it to the fragment in second activity so I need to firstly send it to that Activity (am I correct ?). This is how I create item :
public void savePart() {
Part part = new Part(name,quantity,"","",tag,"","2");
Intent intent = new Intent(this,InvActivity.class);
intent.putExtra("Part", (Serializable) part);
setResult(2,intent);
finish();
}
This is how I receive it in second activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 2) {
part = (Part) data.getSerializableExtra("Part");
}
}
I've got method to return the part in fragment :
public Part getMyData() {
return part;
}
In Fragment's onResume() I receive the Part object, check if object with similar code exists and add it to the ListView if not:
#Override
public void onResume() {
super.onResume();
List<Part>subList = new ArrayList<>();
if (mActivity.getMyData() != null) {
Part part = mActivity.getMyData();
for(Part parts : mParts) {
if (parts.getCode().contains(part.getCode())) {
subList.add(parts);
}
}
if (subList.size() == 0) {
mParts.add(part);
adapter = new PartAdapter(getContext(), R.layout.part_item, mParts, mActivity, new AdapterCallback() {
#Override
public void onMethodCallback() {
}
});
mPartsLV.setAdapter(adapter);
} else {
Toast.makeText(getContext(), R.string.equipment_exists, Toast.LENGTH_SHORT).show();
}
}
}
So far everything works well. items are added correctly and shown in ListVIew in fragment.Here is where the problem begins :) In listView row I've got imageView which deletes item from ListView.
mDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mParts.remove(part);
notifyDataSetChanged();
}
});
That works great to but ... when fragment comes back to onResume() deleted item shows again is ListView. That is because each time I receive Part and check if exists in List. I think I should somehow clear intent after receiving Part from Activity where Part was created but I don't know how ? Maybe any other solution,please ?
Declare your subList as public and populate it once. So you need to modify your onResume function a bit. Check if the list is populated already. If not, populate the list from the extras and vice versa.
ListsubList = new ArrayList<>();
your list is created every time when onResume() called that's why delete entries could not managed. So either take a copy of this list or every time check which elements got deleted,and then set data to listview.

How to pass value via Intent form 1st activity to third?

I need to pass some value from 1st activity into the third. I already pass it form 1st to 2nd like this.
my 1st activity: (I do it in on create method)
mainListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(DisplayRecepit.this, DisplayLogs.class);
intent.putExtra("recepitID", receiptList.get(position).getId());
startActivity(intent);
}
});
And I recieved it in 2nd activity like this: (I do it in on create method)
final long forwardedId = (long) getIntent().getExtras().get(String.valueOf("recepitID"));
List<Logs> logsList = new Select().from(Logs.class).where("Receipt = " + forwardedId).execute();
Now I need somehow pass it from 2nd activity to my third activity.
In my 2nd activity I have a button that takes me to 3rd activity.
I saw some examples on web but I didn't make my app working, so any help is welcome.
Question: I have pass value via intent from 1st activity to 2nd activity. How should I pass this same value from 2nd activity to my 3rd activity?
In your second activity pass this value using intent
Intent i = new Intent(getApplicationContext, Third.class);
i.putExtra("forwardedId",forwardedId);
startActivity(i)
First you have to pass data to 2nd Activity.then you can pass from 2nd to 3rd Activity.
Using default android mechanism its not possible. Still if you cant to achieve this you can use Eventbus : "https://github.com/greenrobot/EventBus" where you post message (can be anything a string, integer, even a class pojo with arrylist) from first activity and catch it anywhere.
Go to above mentioned link add the dependency in your app level build.gradle and sync it.
Create this event Pojo :
public class SomeEvent {
private ArrayList<String> message;
public SomeEvent(ArrayList<String> message) {
this.message = message;
}
public ArrayList<String> getMessage() {
return message;
}
}
Activity 1 :
in onResume() do this :
EventBus.getDefault().register(this);
in onDestroy() do this :
EventBus.getDefault().unregister(this);
to post an event :
Do this only after Eventbus registration.
EventBus.getDefault().post(new SomeEvent(some arraylist);
Now in Activity 3:
just write this method. Don't call it explicitly. Eventbus handles that internally. Make sure the argument of this method is your event class which you post in Eventbus.
public void onEvent(SomeEvent event){
// you got your arraylist which you posted from Activity 1;
ArrayList<String> list = event.getMessage();
}

Android Development: pass information and fail

I got 2 classes in my project. The first class(main) have a listview and this is the onclick():
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
Object o = this.getListAdapter().getItem(position);
String keyword = o.toString();
class2 sec = new Class2();
Intent intent = new Intent(this, Class2.class);
startActivity(intent) ;
if (keyword == "hello"){
sec.setInfo(keyword);
}
}
so and then in my other class which have a defferent layout.xml. The code is:
public class det extends Activity {
static WebView map;
public TextView header;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
}
public void setInfo(String mystring){
header = (TextView) findViewById(R.id.text01);
header.setText(mystring);
//Toast.makeText(this, map, Toast.LENGTH_LONG).show();
//return;
}
Ye, i keep getting force close on my android phone. The App i meant to change the header text to text that ive tapped on the listview. But when i click a item it pop up a window with FC.
ive try to comment away the:
header = (TextView) findViewById(R.id.text01);
header.setText(mystring);
and it worked without a FC however the headertext is stil null.
Thank you!
Your Friend!
First of all, you need to post the stack trace for us to have any idea how to help.
Second, I'm assuming Class2 extends Activity or else Intent intent = new Intent(this, Class2.class); doesn't make any sense. That being the case, class2 sec = new Class2(); is ALWAYS wrong. You never ever call new on a class that extends Activity.
You can't call methods on another activity like that. Your only real option is to send the keyword in the intent by using putExtra, and then getting retrieving it in Class2

Categories

Resources