I have an Android app with a ListView. Every row is generated dinamically by SQLIte query results. When users click on a item, the app should refresh the list with the "content" of that item, generated by another SQLite query, and so on.
I tried to "refresh" the activity creating a new intent and sending it to the same activity. Activity name is ShopActivity
ListView list_content = ((ListView)findViewById(R.id.listforshop));
list_content.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// ID and text of selected item
long selected_id = id;
String selected_name = (String) ((TextView) view.findViewById(R.id.element)).getText();
// New intent
Intent intent = getIntent();
intent.setClassName(ShopActivity.this, ShopActivity.class.getName());
// Passing data and refreshing activity
intent.putExtra("id", selected_id);
intent.putExtra("name", selected_name);
intent.putExtra("type", "");
startActivity(intent);
}
});
In this way LogCat shows me a lot of warnings about Bundle. It seems that app cannot start activity.
Is there another way to "refresh" ListView? Is this implementation correct?
// New intent
Intent intent = getIntent();
intent.setClassName(ShopActivity.this, ShopActivity.class.getName());
This does not make a new Intent, this reuses the existing one... Re-using an Intent like this will throw a lot of warning and exception when you resume this Activity. In order to create a new Intent you need to use the keyword new.
But you don't really need to reload your entire Activity, simply fetch a new Cursor and use CursorAdapter#swapCursor() to refresh your ListView.
When trying to refresh your ListView you should think of using notifyDataSetChanged() of your adapter. this method tells your adapter that the provided data has changed and that it should update the list view.
So you should add the new data to your adapter and then call this method.
Sounds like you're viewing the details, don't use the same activity to view them. Add a new ShopDetailActivity and direct the user there on click, that way the user can press back to go to the original list (plus get the nice transition animation).
Another way of handling lists and details is to use Fragments. The advantage of this is that on large-screen devices, both the list and the detail can be visible at the same time.
Using one Activity to show both list and detail is messy. At the very least, use two Activities.
Related
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 a ListView and from a click on an item of the ListView I call the Storage Access Framework (SAF).
Just before starting the SAF, I want to pass the position of the ListView like this:
intent.putExtra("Position", position);
startActivityForResult(intent, WRITE_REQUEST_CODE);
But how do I get the position back in the onActivityResult() method so I know which item is clicked?
I tried these lines, but with no success:
Bundle extras = resultData.getExtras();
Integer i = getIntent().getIntExtra("routeDataPosition", 42);
Integer i2 = resultData.getIntExtra("routeDataPosition", 42);
Just before starting the SAF, I want to pass the position of the ListView like this:
That does not work. You cannot force extras into another app, and you cannot force another app to return those extras.
But how do I get the position back in the onActivityResult() method so I know which item is clicked?
You could store it in a field in your activity, fragment, or viewmodel.
If you wanted to get elaborate, you could use a different request code based on the position. So, instead of WRITE_REQUEST_CODE, use WRITE_REQUEST_CODE + position. You would need to have smarts in onActivityResult() to get the position back out of the result code (e.g., position = resultCode - WRITE_REQUEST_CODE).
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.
I'm new to Android development.
I created a simple master-detail app that starts with a simple, vertical scrolling list of topics.
When the user selects a topic, a details screen appears, replacing the first screen, with a list of details that pertain to the selected topic.
I want the title for the details screen to show the topic the user has selected on the first page, but haven't been able to solve the problem after working for almost a week.
All I need to know is, Can this be done? Not looking for someone to solve this for me, but maybe a hint or a link to a tutorial that shows how this can be done.
Note: I'd post a drawing of what I want to do, but I'm new here and don't have 10 reputation yet.
Thanks,
SonCoder
Not exactly sure what you want but either way..
-You have a listview. Each view (the data) in the listview should be a represented by a model. (aka a separate class containing specific information that you want to represent for each listitem.
-Write a custom list adapter (extend from base adapter).
http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
In the getView method of this class you load the the String field of the model that you want in the textview.
-Make sure to use the viewholder pattern in the adapter above. I noticed the example doesnt use one. This speeds up scrolling in the list because there are much fewer calls to findViewById.
-in the list activity set up a View onClick listener. This should create an intent (for launching an activity) or a fragment transaction (for fragments). Send the instance of your entire model (will get from
parent.getAdapter().getItem(position);
in the on click method) into the detail activity.
-if you want to set a textview title just get the textview and set it from the model. It will be the same filed you inflated in the getView method of the adapter.
-if you want to set the titile in the actionbar set:
this.getActionBar().setTitle(title)
This is simple. Just send extra data in the intent that starts the activity and then in the activity's onCreate read the data and then use the setTitle(myString) method from the activity.
setTitle(String title) can be called from anywhere using the activity by the way.
So, your in your listadapter, then you set a listener on your view right? A simple onClickListener on the whole "root" view is just fine.
In the listener you say something in the ways of this:
Intent intent = new Intent(myActivity, MySubActivity.class);
intent.putExtra(key, titleName);
myActivity.startActivity(intent);
Note that the activity reference should be set in the constructor of the adapter and that the "key" String is something you get from your strings.xml. Do not duplicate these in code since if you change one and forget to change the others you might get some wierd NPEs.
Continue in your MySubActivity's onCreate()
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String key = getString(R.string.my_title_key);
String title = intent.getString(key);
setTitle(title);
}
NOTE: I'm not sure of all method names are correct and such but something like this.
I have some Acitivity with a ListView.
I want that after clicking the ListView item there should be new Activity with the same type of layout contains another info(e.g.ListView) related to the clicked item.
I have known that there is not way to create dynamically Activities.
What should I do to be able to go from one Layout to another(by clicking ListView items) and should be able to go back in the same back-sequence by back-key?
I have known that there is not way to create dynamically Activities.
What should I do to be able to go from one Layout to another(by
clicking ListView items) and should be able to go back in the same
back-sequence by back-key?
Why can't you create activities dynamically? You can easily create a new one from your ListView onclick listener
lv.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
//Based on the position of the clicked item create a new activity with the position id
Intent intent = new Intent(currentActivity.this, newActivity.this);
intent.putExtra("id", position);
startActivity(intent);
}
};
And now in the newActivity you would check what is the passed id by doing
Bundle bundle = getIntent().getExtras();
theId = bundle.getInt("id");
//Now do something based on that id
Pressing on the back key from the new activity should take you back to the previous one
You can use A Fragment to implements your ListView:
http://developer.android.com/reference/android/app/ListFragment.html
then you can simply replace the current ListFragment with a new one by using the FragmentManager class and the FragmentTransation class. In this way the FragmentManager will take care of replacing the new ListFragment with the old one when you press the back button.
Be careful since if you use ListFragment your SDK target must be 11 or more. If this is a concern for you, you can use the class Fragment from the support library putting inside it a ListView. FragmentManager and FragmentTransation are also part of the support library.