I'm trying to build an application that will have list/detail panes built with fragments. List is created from the ContentProvider. When clicked on the list the details is populated or activity created. In action similar to gmail application. How the data should be shared/passed between fragments/activities?
Population of the list wasn't that hard, but how can I pass the selection to the details fragment (either in the same activity or another activity)? Should I query again and returned result used in details?
It needs to be like gmail app, so swipe left/right should then change the details accordingly to the same order as the list is either in the single pane layout or dual pane layout.
I think for this I need to share the Cursor returned by the CursorLoader to keep the same order. Then swipes would increase/decrease the index and would display correct item.
Also as I already loaded data, I wanted to reuse it without new queries.
Could someone point me to the right direction, what you would you do to achieve that (no code but algorithm/steps)?
At the moment I have 2 activities list and detail, the list has dual and single panel layout and list fragment with details fragment are used, detail has just single pane with details fragment. I think I could reduce it to be a single activity and juggle the fragments but don't know if it will be good.
Here is a way to pass data from one activity to another :
intent = new Intent(this, ProductListActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable(PRODUCT_LIST, productList);
bundle.putString(KEY_WORD, keyWord);
intent.putExtras(bundle);
startActivity(intent);
If you're in an activity and want to pass data to a fragment in that activity, just use setters from that fragment
EDIT : Since last comment, implement a class to handle your object with the Serializable interface :
public class MyDBObject implements Serializable {
//Stuff
}
Then when you fetch from your DB, return or a MyDBObject, or a List<MyDBObject>
Finally, when you need to pass the data, just use
Intent intent = new Intent(SourceActivity.this, TargetActivity.class);
intent.putExtra("DB_OBJECTS", ArrayList<MyDBObject>mDBObject); // For a list
intent.putExtra("DB_OBJECT", mDBOject); //For a single object
What I did then was:
activity holding the fragment(s) will do:
implement LoaderManager.LoaderCallbacks<Cursor>
call the getSupportLoaderManager().initLoader(ALL_DATA_LOADER_ID, null, this);
pass arguments of the LoaderCallbacks to the fragments that also implements LoaderCallbacks
call the getSupportLoaderManager().restartLoader(ALL_DATA_LOADER_ID, null,
this); whenever data was changed outside of the ContentProvider means
This way I'm sharing the same cursor between fragments. Between activities I'm exchanging (via Intent) the data needed to request the same dataset and selection id if needed.
Related
There is a fragment which contains three RecyclerViews (all of three contain CardViews). One recycler displays city names and second displays fuel types. The third recycler is supposed to display filling stations and corresponding prices for selected city and fuel type.
All data is stored in MySQL database on web-server and query is written in a PHP file. I have adapters for all 3 recyclers, and the question is how to display data in the third recycler when user clicks on the first or the second recycler, all of that in one fragment. Data is sent to query from first and second recycler, while the result should be displayed in third.
If needed, I will post my code (fragment, adapter or anything else you need).
I am relatively new in 'Android programming' and I would really appreciate some help with this case.
I have already searched for the solution, but there was no complete or correct solution for it.
Thank you!
If you want to pass the data from the fragment to an activity you can pass it with intent.putExtra.
from a fragment to an activity, in the adapter you will do:
Intent intent = new Intent (context, NameOfActivity.class);
intent.putExtra ("nameFromArgument", value);
context.startActivity (intent);
in the activity that will receive the fragment data you will do, within onCreate:
Extra bundle = getIntent (). GetExtras ();
String received = extra.getString ("nameFromArgument");
after that you will get the data from the received string that came from the adapter and will pass it in your request, if you want to pass more than one parameter to the activity, just repeat intent.putExtra always changing the nameFromArgument and receiving the same way in the activity, you too you can pass an object if you want
I have a database and adapter for the first activity showing the name and description. There is a button on each list item which takes you to the second activity displaying a unique image related to that item.
I have included an Intent from the first activity to the second activity.
So on the second activity I would like to add the image related to the item clicked.
Question:
(a)Do I include the image in the same database for the first activity or do I need a separate database and adapter for the second activity?
(b)Also do I need to create a separate intent for each item in the first activity as each item has a separate image that it will link to via the button which will be displayed on the second activity.
Your click listener will be one and generic as same lite item view is inflated for all items of adapter.
2.on click you need to pass the Uri string to second activity via intent and display the image Uri in second activity after receiving it from getIntent() in oncreateview() of second activity.
I would like to answer this in two parts.
Part 1: the database: You should use the same table for the image as well. You can always talk to the same database and all the tables from any activity, so no need to have a separate database. So the name, description and image in the same activity.
Part 2: The intent
If you are in a scenario where you have to add any action on click of an adapter item, always use a callback.
When you click on any item, this callback will tell you in the activity that which item in the adapter is clicked.
This medium blog is a very good example to demonstrate this.
In this blog's code, there is a block in adapter where you pass the values from the activity. It is the constructor.
RecyclerViewAdapter(RecyclerViewClickListener listener) {
mListener = listener;
}
If you had added some code, it would help, but I am sure you also have this constructor in your code, so add this listener along with the other data and see how it works out.
Thanks
I have two activities where they have almost same data, I am using same Adapter, But the problem is how to sync data.
E.g.
Activity A has recyclerview where it has like buttons in each row with unique id. Activity B also have same recyclerview but with some filter mechanism so it is not going to show all row, my question is how to handle like button state in Activity A and Activity B, such that if I click on activity B's like button than activity A's like button will automatically gets checked and vice versa.
You should use common data source for both the recycler views.
Get data from API
Save data in your local db
Feed the data to your Activity A recycler view
Feed the same data to your Activity B recycler view
All the changes you make to data should be in local db so both the
views can update automatically.
you can use static modifier
define BaseRecyclerView which has a static list of the items
extend CustomRecyclerView's from BaseRecyclerView
when you manipulate the items in list such as setting like flag the list in two CustomRecyclerView's will be changed because of static modifier
Manage Locally:
Your same list of data should be accessible in both of the activities. You can save that list in your application class. And if you don't want to save in Application class then on every switch of Activity you have to pass that list data between both activities.
Next thing in Model class you have to make one more variable to save a state for like button, once you make it like then I should save that value and when you went to retrieve that same list data it will give you updated data for like button event.
Through code you can achieve:
class MyApplication extends Application{
public static ArrayList<MyModel> myModelList = new ArrayList<>();
}
class MyModel{
public boolean isLikeSelected;
}
Activity A:
onLikeClick(int position){
MyApplication.myModelList.get(position).isLikeSelected = !MyApplication.myModelList.get(position).isLikeSelected;
adapter.notifyItemChanged(position);
}
Activity B:
onLikeClick(int position){
MyApplication.myModelList.get(position).isLikeSelected = !MyApplication.myModelList.get(position).isLikeSelected;
adapter.notifyItemChanged(position);
}
Here your application class is having static ArrayList which can be accessible throughout the app and have a stable and updated record of list data.
Using Server:
On every click at like button you will update to the server for the event and next time on Activity switch you will get updated list from the server, so no need to worry in case of server management.
i have 2 fragments
in 1st fragment i am calling a 2nd fragment on button click which returns data(on click on list items) and again open 1st fragment with the result displayed (i.e some String data of list item).
But the problem is when i comeback from 2nd to 1st again after selection in 2nd fragment my 1st fragment is displayed only but do not react on button click.
this is my first fragment
i have searched lot but i found activity fragment communication only not fragment to fragment
if any body has solution for fragment to fragment only.please help
There are a lot of ways, here some hints.
Generally speaking you can use "listeners" (interfaces)
Official Google Docs
Similar question on StackOverflow
More elegant way using "event bus" paradigm, a clean and simple library is Otto
Another (slightly dirty) way if you are using the compatibility library would be to use the LocalBroadcastManager. Your fragments can send (and listen for) local broadcasts to notify each other of events...
Try like this (Example an integer array):
//Create a public class:
public class Values{
public static int[] val = null;
}
//Set array in one fragment:
Values.val = int[] arr1;//arr1 containing your values
//Get array in another fragment:
int[] arr2 = Values.val;
I currently have a tab layout with 2 tabs, one tab with a list view and one with the option make strings so I can add them in the list view. Both tabs have their own activity because this made the code much more structured, and I dont have to repeat my self later.
Lets say im in the tab that offer me to create an string, and i press the update list button, how do I update the list view without startActivity()? If i use startActivity(), it starts List.java, and instead of displaying the list in the list view tab, it takes full screen, which defies the purpose of the tab view. In other words, the startActivity() steals the focus from the tab view of the list, and sends it fulscreen.
Thanks for your time.
Edit: I want to update the activity in my list view tab, without starting a new activity that goes to fullscreen, and doesnt update the one in the tab.
One solution is to have your data model separate from your view (Activity), this is good practice in general, but in this case allows your two tabs to interact with the same model.
You could provide access to the data model in your Application class. Then, when onResume is called on your list activity you can update the view based on the current data.
edit:
public class MyApplication extends Application {
private List<MyObject> myData;
public List<MyObject> getMyData() {
return myData;
}
public void setMyData(List<MyObject> mydata) {
this.myData = myData;
}
}
In your manifest you need to add the application tag to specify that it should use MyApplication as the application class.
Then, in your activity:
public void onResume() {
MyApplication app = (MyApplication) getApplication();
List<MyData> data = app.getMyData();
// update my view with the data
}
I had the same problem when i was making my app and the only solution i found was to add this flag to my intent so every time i go to the tab it would refresh it self
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
I hope it helps.