The titles explains all of the problem, I'll provide extra info here.
I have a code in my MainActivity that calls a
Code:
mContactListFragment.notifyInvalidated();
method.
This is the method
Code:
public void notifyInvalidated() {
Log.w(MainActivity.TAG, "" + _viewExists);
Log.w(MainActivity.TAG, "The not still casted object is " + getListAdapter());
Log.w(MainActivity.TAG, "The casted object is " + (BaseAdapter)getListAdapter());
((BaseAdapter) getListAdapter()).notifyDataSetInvalidated();
}
All of the above prints false, null, null, and then the program crashes at the 4th instruction.
_viewExists is a variable that's initialized to false as soon as it's created and it's touched in no other part but in the onCreateView() method that sets it to true.
So while debugging, I arrived to the conclusion that nothing works because onCreateView() is not actually called, even though my Fragment is on the screen.
This happens after I rotated the device and I'm in landscape mode.
If I report the device in portrait mode (from landscape to portrait again) and try to call that method, all is good.
I am not sure what other code you would want to see, just ask.
I have to admin I am tired of problems involving fragments and rotations (configuration changes), what would you suggest me to read?
domenicop said:
The titles explains all of the problem, I'll provide extra info here.
I have a code in my MainActivity that calls a
Code:
mContactListFragment.notifyInvalidated();
method.
This is the method
Code:
public void notifyInvalidated() {
Log.w(MainActivity.TAG, "" + _viewExists);
Log.w(MainActivity.TAG, "The not still casted object is " + getListAdapter());
Log.w(MainActivity.TAG, "The casted object is " + (BaseAdapter)getListAdapter());
((BaseAdapter) getListAdapter()).notifyDataSetInvalidated();
}
All of the above prints false, null, null, and then the program crashes at the 4th instruction.
_viewExists is a variable that's initialized to false as soon as it's created and it's touched in no other part but in the onCreateView() method that sets it to true.
So while debugging, I arrived to the conclusion that nothing works because onCreateView() is not actually called, even though my Fragment is on the screen.
This happens after I rotated the device and I'm in landscape mode.
If I report the device in portrait mode (from landscape to portrait again) and try to call that method, all is good.
I am not sure what other code you would want to see, just ask.
I have to admin I am tired of problems involving fragments and rotations (configuration changes), what would you suggest me to read?
Click to expand...
Click to collapse
I've had these problems, too. They're really annoying.
Could you please post your code where the Fragment is created, the onCreate method of the Fragment and the onCreate method of the Activity?
You have to use (override) onActivityCreated for that.
Taptalked u see .. əəs n pəʞlɐʇdɐʇ
nikwen said:
I've had these problems, too. They're really annoying.
Could you please post your code where the Fragment is created, the onCreate method of the Fragment and the onCreate method of the Activity?
Click to expand...
Click to collapse
Sure, here they are.
Fragment
Code:
public static ContactListFragment newInstance(ContactsDatabase database) {
ContactListFragment f = new ContactListFragment();
Bundle args = new Bundle();
args.putSerializable(DATABASE, database);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mDatabase = (ContactsDatabase) args.getSerializable(DATABASE);
}
Activity
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentByTag(CONTACTS_PAGER_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
}
Zatta said:
You have to use (override) onActivityCreated for that.
Taptalked u see .. əəs n pəʞlɐʇdɐʇ
Click to expand...
Click to collapse
Could you elaborate a little bit on that? Where should I use onActivityCreated? I need to use notifyDataSetChanged() whenever a button is pressed. Maybe you're talking about the variable.
I don't really need the _viewExists variable, it was only created to debug the problem.
domenicop said:
Sure, here they are.
Fragment
Code:
public static ContactListFragment newInstance(ContactsDatabase database) {
ContactListFragment f = new ContactListFragment();
Bundle args = new Bundle();
args.putSerializable(DATABASE, database);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mDatabase = (ContactsDatabase) args.getSerializable(DATABASE);
}
Activity
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentByTag(CONTACTS_PAGER_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
}
Click to expand...
Click to collapse
domenicop said:
Could you elaborate a little bit on that? Where should I use onActivityCreated? I need to use notifyDataSetChanged() whenever a button is pressed. Maybe you're talking about the variable.
I don't really need the _viewExists variable, it was only created to debug the problem.
Click to expand...
Click to collapse
After the fragment is created is stays created. When you rotated the device the onCreate of the activity is called again but not the onCreateView of the fragment. However, the onActivityCreated in the fragement is.
See for reference http://developer.android.com/guide/components/fragments.html#CoordinatingWithActivity
Your explanation was crystal clear.
However, the developer reference was not that help.
In the article you linked, it says to watch at figure 3 and notice how when the activity is created, the fragment will receive only the onActivityCreated() callback.
The flow of a fragment's lifecycle, as it is affected by its host activity, is illustrated by figure 3. In this figure, you can see how each successive state of the activity determines which callback methods a fragment may receive. For example, when the activity has received its onCreate() callback, a fragment in the activity receives no more than the onActivityCreated() callback.
Click to expand...
Click to collapse
This is Figure 3
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
I need to know which activity callback affects which fragment callback but I can't extrapolate anything from here.
Should I worry about my sight/cognitive decline?
Also, there is a main problem with the way I add fragments to the layout, I just noticed.
Basically, look at this code in MainActivity.java
Code:
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentByTag(CONTACTS_PAGER_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
When I am in dualPane mode, the mContactListFragment won't be on the screen.
That happens because
Code:
(ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
does not return null even though the fragment is not in the layout (it look for fragments in the BackStack in that case).
I fixed this explicitly checking for that case:
Code:
(mContactsPagerFragment == null || !mContactListFragment.isInLayout())
but I still have a doubt: Should the fragment be treated in another way when found in the BackStack?
Maybe I can take it back on top of the stack, refreshing its view?
I ask this because it seems like a candidate to performance issue, or worse, something that could result in the creation of double/triple fragment running on the activity (with just one of them visible, of course)
Sorry if the explanation was messy, bring that up and I'll try to reformulate the problem in other words.
Thank you guys
Zatta said:
After the fragment is created is stays created. When you rotated the device the onCreate of the activity is called again but not the onCreateView of the fragment. However, the onActivityCreated in the fragement is.
See for reference http://developer.android.com/guide/components/fragments.html#CoordinatingWithActivity
Click to expand...
Click to collapse
No, the Fragments are destroyed when the Activity is destroyed. However, you can call
Code:
setRetainInstance(true)
in the Fragment code/onCreate method so that it won't be destroyed. But in general Fragments are destroyed when the Activity is destroyed.
Aditionally, the setRetainInstance() method is meant to be used with Fragments without UI only. That way you can use it to execute background tasks. (It does work with UI Fragments, too, but it's bad practice.)
Evidence:
If an activity stops, its fragments are also stopped; if an activity is destroyed its fragments are also destroyed.
Click to expand...
Click to collapse
Source: http://www.vogella.com/articles/AndroidFragments/article.html#usingfragments_lifecycle
---------- Post added at 07:51 PM ---------- Previous post was at 07:38 PM ----------
domenicop said:
Also, there is a main problem with the way I add fragments to the layout, I just noticed.
Click to expand...
Click to collapse
Exactly, that's why the onActivityCreated() method isn't called.
You create the Fragments after the Activity has been created. So it wouldn't make sense to call that method. Maybe you could use onAttach() instead.
Try to do the dual pane implementation like this: http://developer.android.com/guide/components/fragments.html#Example
(Or use the template in Android Studio/Eclipse.)
nikwen said:
No, the Fragments are destroyed when the Activity is destroyed. However, you can call
Code:
setRetainInstance(true)
in the Fragment code/onCreate method so that it won't be destroyed. But in general Fragments are destroyed when the Activity is destroyed.
Aditionally, the setRetainInstance() method is meant to be used with Fragments without UI only. That way you can use it to execute background tasks. (It does work with UI Fragments, too, but it's bad practice.)
Evidence:
Source: http://www.vogella.com/articles/AndroidFragments/article.html#usingfragments_lifecycle
Click to expand...
Click to collapse
I should have replied before that all is good if I add the adapter from the onActivityCreated callback.
I also knew about fragment being destroyed when the activity is destroyed when setRetainInstance() was not called.
Maybe when fragments are recreated, the callbacks invoked are just a sub-set of the original one.
PS. Have you read my previous post?
domenicop said:
PS. Have you read my previous post?
Click to expand...
Click to collapse
I did. Check my answer. (Did it one by one.)
nikwen said:
Exactly, that's why the onActivityCreated() method isn't called.
You create the Fragments after the Activity has been created. So it wouldn't make sense to call that method. Maybe you could use onAttach() instead.
Click to expand...
Click to collapse
I didn't follow your line of thought, could you please re-elaborate?
nikwen said:
Try to do the dual pane implementation like this: http://developer.android.com/guide/components/fragments.html#Example
(Or use the template in Android Studio/Eclipse.)
Click to expand...
Click to collapse
I can't because I need to dynamically change them later and this wouldn't be possible with the static xml initialization.
Fragments present in XML, can't be .remove()'ed.
domenicop said:
I didn't follow your line of thought, could you please re-elaborate?
Click to expand...
Click to collapse
Sorry, forget about the first part of my post. Just checked the documentation:
onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
Click to expand...
Click to collapse
(Source: http://developer.android.com/reference/android/app/Fragment.html)
I can't because I need to dynamically change them later and this wouldn't be possible with the static xml initialization.
Fragments present in XML, can't be .remove()'ed.
Click to expand...
Click to collapse
Why can't you remove them?
---------- Post added at 08:13 PM ---------- Previous post was at 08:09 PM ----------
nikwen said:
Sorry, forget about the first part of my post. Just checked the documentation:
(Source: http://developer.android.com/reference/android/app/Fragment.html)
Click to expand...
Click to collapse
OK, don't forget about it. Checked it again. :laugh:
The commit() method of FragmentTransaction:
Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.
Click to expand...
Click to collapse
http://developer.android.com/reference/android/app/FragmentTransaction.html#commit()
This means that the Fragment is added after the Activity has finished the onCreate() method.
However, the onActivityCreated() method is just called when the onCreate() method of the Activity has finished. In this case the Fragments doesn't exist at that time. So the method cannot be called.
Does it make sense now?
---------- Post added at 08:17 PM ---------- Previous post was at 08:13 PM ----------
One more try:
Activity is created
FragmentTransaction is sheduled
onCreate() finishes
No Fragment whose onActivityCreated() method can be called exists
Fragment is created
onActivityCreated() isn't called as it's just called when the Activity's onCreate() method finishes (on all Fragments that exist at that time).
nikwen said:
Activity is created
FragmentTransaction is sheduled
onCreate() finishes
No Fragment whose onActivityCreated() method can be called exists
Fragment is created
onActivityCreated() isn't called as it's just called when the Activity's onCreate() method finishes (on all Fragments that exist at that time).
Click to expand...
Click to collapse
Nice catch man!
I tried to just initialize the adapter onCreate() and all is good.
Do you have any particular reason for indicating onAttach()?
I have to say if it wasn't for this list though, I thought you were just going crazy making things up
Also I've to ask one thing at this point, why do you say that the fragments are not created when the onCreate() method ends?
Aren't they initialized inside that method?
domenicop said:
Nice catch man!
I tried to just initialize the adapter onCreate() and all is good.
Do you have any particular reason for indicating onAttach()?
I have to say if it wasn't for this list I though you were just going crazy making things up
Click to expand...
Click to collapse
Haha. Great. :laugh:
Why I talked about onAttach(): At that point you can be sure that there's an Activity which is available via getActivity().
But if it works for you now, don't change it.
---------- Post added at 09:15 PM ---------- Previous post was at 09:10 PM ----------
domenicop said:
Also I've to ask one thing at this point, why do you say that the fragments are not created when the onCreate() method ends?
Aren't they initialized inside that method?
Click to expand...
Click to collapse
Ah, I haven't been accurate enough. Should have been like this:
Activity is created
Fragment is created
FragmentTransaction is sheduled
onCreate() finishes
No Fragment whose onActivityCreated() method can be called is attached to the Activity
Fragment is added to the Activity
onActivityCreated() isn't called as it's just called when the Activity's onCreate() method finishes (on all Fragments that exist at that time).
It's being created during onCreate() but it's added to the Activity later. That's why there's no attached Fragment whose onActivityCreated() method can be called.
And why it's added later:
The commit() method of FragmentTransaction:
Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.
Click to expand...
Click to collapse
http://developer.android.com/reference/android/app/FragmentTransaction.html#commit()
Related
Hello,
I'm new to developing software in Java, but especially with Android. I am going through a tutorial on how to create an RSS Feed Reader and so far I've got it mostly working, but I've got a few bugs I can't seem to figure out.
I wanted to post images, but it wouldn't let me, but anyway:
main activity - title, pubdate both work, as does each article's title.
after clicking on a title, the other activity is launched and the article is shown:
showdescription activity is launched - title, pubdate, link all work and display correctly.
bug: description does not always display everything or even display at all depending on the xml source.
I'm wondering if my problem is somewhere these code snippets, as this tutorial was written some time ago.
These are pretty basic, so I'm doubting the problem is in here.
RSSHandler said:
if (localName.equals("description"))
{
currentstate = RSS_DESCRIPTION;
return;
}
...
case RSS_DESCRIPTION:
_item.setDescription(theString);
currentstate = 0;
break;
Click to expand...
Click to collapse
RSSItem said:
void setDescription(String description)
{
_description = description;
}
...
String getDescription()
{
return _description;
}
Click to expand...
Click to collapse
This is where I believe the problem exists, in the onItemClick method or the ShowDescription class.
RSSReader said:
public void onItemClick(AdapterView parent, View v, int position, long id)
{
Log.i(tag,"item clicked! [" + feed.getItem(position).getTitle() + "]");
Intent itemintent = new Intent(this,ShowDescription.class);
Bundle b = new Bundle();
b.putString("title", feed.getItem(position).getTitle());
b.putString("description", feed.getItem(position).getDescription());
b.putString("link", feed.getItem(position).getLink());
b.putString("pubdate", feed.getItem(position).getPubDate());
itemintent.putExtra("android.intent.extra.INTENT", b);
//startSubActivity(itemintent, 0);
startActivity(itemintent);
}
Click to expand...
Click to collapse
ShowDescription said:
public class ShowDescription extends Activity
{
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.showdescription);
String theStory = null;
Intent startingIntent = getIntent();
if (startingIntent != null)
{
Bundle b = startingIntent.getBundleExtra("android.intent.extra.INTENT");
if (b == null)
{
theStory = "bad bundle?";
}
else
{
theStory = b.getString("title")
+ "\n\n" + b.getString("pubdate")
+ "\n\n" + b.getString("description")
+ "\n\nView Website:\n" + b.getString("link");
}
}
else
{
theStory = "Information Not Found.";
}
TextView db= (TextView) findViewById(R.id.storybox);
db.setText(theStory);
Button backbutton = (Button) findViewById(R.id.back);
backbutton.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
finish();
}
});
}
}
Click to expand...
Click to collapse
Originally the tutorial called for "startSubActivity" for starting the ShowDescription activity, but that doesn't seem to exist anymore?
The XML source I'm using can't be displayed because I can't link in outside pages, but I can PM it to you if you'd like.
I have tried using a .replaceAll("\\<.*?>","") but it didn't seem to change much about whether the <description> tag's content is displayed or not.
Anyway, if anyone takes the time to look at this, it'd be greatly appreciated, and thank you!
If you need me to post anymore code let me know.
So I think I've figured it out, well somewhat.
While stepping through the code, the <description> tag's content consists of a single < character. Then the parser goes through two more tags that contain, p and > before actually hitting the content I want.
So it looks something like this:
<description>
<
<?>
p
<?>
>
<?>
"wanted content"
</?>
</?>
</?>
</description>
Click to expand...
Click to collapse
I have been using a hand built ListActivity as my AppWidget config Activity but to be honest it looks ****ty and doesnt fit in with the rest of the app. So i wanted to transition over to a PreferenceActivity. i made a stub of a PreferenceActivity that launches the layout just fine when it is the main activity. but when i try to change from my ListActivity to my PreferenceAcitivity i get no launching of PreferenceActivity when i launch my widget. all i get is my widget.
i did a refactoring of my xml files to change the instances of my ListActivity (GITextConfig) to my PreferenceActivity (GITextPreferences).
how can i use a PreferenceActivity as my config?
do i need to have a dummy Activity be the config with a button to launch the PreferenceActivity? cause that works just fine. its lame and shouldnt be that way... nvm that does not work... i just cant get a prefs activity to run from an appwidget
anyone? this is quite annoying... i know it can be done as other widgets like gmail unread count does this. at least it appears to have a preferenceactivity as the configuration
got it to work. i dont know what i was doing before but i think i had a little too much of a stub for it to work. after i implemented the appwidget id verification and created my PreferenceManger and overode the onBackPressed() method it seems to work.... happy and confused.
Code:
public class GITextPreferences extends PreferenceActivity {
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager localPrefs = getPreferenceManager();
localPrefs.setSharedPreferencesName("GITC_Prefs");
addPreferencesFromResource(R.xml.gitc_preferences);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
}
@Override
public void onBackPressed() {
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
}
hello
I am new to android application development and i am developing and application for learning purpose.
Can any body please help me in creating an activity that launch and activity on ListView Item Click.
I am using Following code for Populating Listview Items.
filename: activity_menu.java
package com.my.android.app;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.app.LauncherActivity.ListItem;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class activity_menu extends Activity {
String[] countries = new String[] {
"Contacts",
"SMS",
"Files & Photos",
"Prefrences",
"Logout",
};
// Array of integers points to images stored in /res/drawable-ldpi/
int[] flags = new int[]{
R.drawable.phonebook,
R.drawable.sms,
R.drawable.filesphotos,
R.drawable.settings,
R.drawable.key,
};
// Array of strings to store currencies
String[] currency = new String[]{
"Manage Contacts Backup",
"Manage SMS Backup",
"Manage files & Photos Backup",
"Set your prefrences",
"Logout of Application",
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
// Each row in the list stores country name, currency and flag
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(int i=0;i<5;i++){
HashMap<String, String> hm = new HashMap<String,String>();
hm.put("txt", countries);
hm.put("cur", currency);
hm.put("flag", Integer.toString(flags) );
aList.add(hm);
}
// Keys used in Hashmap
String[] from = { "flag","txt","cur" };
// Ids of views in listview_layout
int[] to = { R.id.flag,R.id.txt,R.id.cur};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to);
// Getting a reference to listview of main.xml layout file
ListView listView = ( ListView ) findViewById(R.id.listview);
// Setting the adapter to the listView
listView.setAdapter(adapter);
}
}
Please help on this. waiting for Responses.
Try this
Code:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
// Do your action here
}
});
There are multiple ways. If using a ListFragment/ListActivity, onListItemClick can also be used. However, I think that that is used especially with a programmatically-defined ListView.
If you want to start a new Activity, do some research about Intents.
SagiLo said:
Try this
Code:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
// Do your action here
}
});
Click to expand...
Click to collapse
This. Use the position parameter if you want it to only open when a particular item is clicked (It is zero-based, if I remember correctly)
Then, to open the Intent:
Code:
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
Opening on any listitem click:
Code:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
}
});
Opening on a specific item:
Code:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
if (position == ITEM_POSITION_HERE)
{
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
}
}
});
how so i implement the code to open new activity on row cick?
cyr0s said:
This. Use the position parameter if you want it to only open when a particular item is clicked (It is zero-based, if I remember correctly)
Then, to open the Intent:
Code:
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
Opening on any listitem click:
Code:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
}
});
Opening on a specific item:
Code:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
if (position == ITEM_POSITION_HERE)
{
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
}
}
});
Click to expand...
Click to collapse
How do i implement this code in my main activity's java file?
suppose, i have a main activity which contains the listview and i have another activity "Activity_game"
and i want to open Activity_game on clicking the first row,
so i put "0" at "ITEM_POSITION_HERE" and "game" at the place of "ActivityName"
but it gives my a bunch of errors and it doesn't work
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
if (position == ITEM_POSITION_HERE)
{
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
}
}
});
nnnn1111 said:
How do i implement this code in my main activity's java file?
suppose, i have a main activity which contains the listview and i have another activity "Activity_game"
and i want to open Activity_game on clicking the first row,
so i put "0" at "ITEM_POSITION_HERE" and "game" at the place of "ActivityName"
but it gives my a bunch of errors and it doesn't work
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
if (position == ITEM_POSITION_HERE)
{
Intent myIntent = new Intent(getApplicationContext(), ActivityName.class);
startActivity(myIntent);
}
}
});
Click to expand...
Click to collapse
We need to know which errors you get.
Read this: http://forum.xda-developers.com/showthread.php?t=2439748
one question
nikwen said:
We need to know which errors you get.
Read this: http://forum.xda-developers.com/showthread.php?t=2439748
Click to expand...
Click to collapse
my problem is , when i run the app, it doesn't show any rows , not even any listview , or string
(just blank white page)
i have two activities
first one is Activity_main.xml in which ive implemented listview
here is it's java file
package com.example.desi;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
public class MainActivity extends Activity {
String[] items = { "item 1", "item 2", "item 3", "item 4", "item 5" };
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
switch( position )
{
case 0: Intent newActivity = new Intent(this, Munda.class);
startActivity(newActivity);
break;
}
}
}
and another activity is Activity_munda.xml
so, i want to run "Activity_munda" through on row click of listview
i also want to have many activities later in my app
my project is error free right now
do you think i have incomplete code?
nnnn1111 said:
my problem is , when i run the app, it doesn't show any rows , not even any listview , or string
(just blank white page)
i have two activities
first one is Activity_main.xml in which ive implemented listview
here is it's java file
package com.example.desi;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
public class MainActivity extends Activity {
String[] items = { "item 1", "item 2", "item 3", "item 4", "item 5" };
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
switch( position )
{
case 0: Intent newActivity = new Intent(this, Munda.class);
startActivity(newActivity);
break;
}
}
}
and another activity is Activity_munda.xml
so, i want to run "Activity_munda" through on row click of listview
i also want to have many activities later in my app
my project is error free right now
do you think i have incomplete code?
Click to expand...
Click to collapse
Your code is incomplete. You haven't populated the layout "activity_main.xml" here. and haven't added the list view, So it is indeed correct the app displays a blank page with no errors.
vijai2011 said:
Your code is incomplete. You haven't populated the layout "activity_main.xml" here. and haven't added the list view, So it is indeed correct the app displays a blank page with no errors.
Click to expand...
Click to collapse
Right. Read this: http://www.vogella.com/articles/AndroidListView/article.html
i already tried that
vijai2011 said:
Your code is incomplete. You haven't populated the layout "activity_main.xml" here. and haven't added the list view, So it is indeed correct the app displays a blank page with no errors.
Click to expand...
Click to collapse
but with no luck
its very complicated
can you please give me a simple tutorial ?
please dont refer to any other tutorial as i have already tried all of them,
thanks
nnnn1111 said:
but with no luck
its very complicated
can you please give me a simple tutorial ?
please dont refer to any other tutorial as i have already tried all of them,
thanks
Click to expand...
Click to collapse
Come on, you haven't tried all of them. Please don't let everyone else do the work for you. And if you can manage to do it yourself, it will be a better learning experience.
I can offer that you try the tutorial I posted and if your code doesn't work, you can post it together with a logcat and we'll check it.
haha i know
nikwen said:
Come on, you haven't tried all of them. Please don't let everyone else do the work for you. And if you can manage to do it yourself, it will be a better learning experience.
I can offer that you try the tutorial I posted and if your code doesn't work, you can post it together with a logcat and we'll check it.
Click to expand...
Click to collapse
but ive been searching for like 15 days about this problem on stack overflow , saw like 30 posts but they arent clear , please do me a favor and
tell me in few steps you will also feel good helping me.
and it will be a VERY big favor to me , trust me
nnnn1111 said:
but ive been searching for like 15 days about this problem on stack overflow , saw like 30 posts but they arent clear , please do me a favor and
tell me in few steps you will also feel good helping me.
and it will be a VERY big favor to me , trust me
Click to expand...
Click to collapse
Read this about ListActivity. It should answer your questions: http://www.vogella.com/articles/AndroidListView/article.html#listactivity
And I won't post step by step guides on how to implement ListViews. There are many great tutorials out there. I can help you if you have problems/errors with your code, but @vijai2011 has already explained what you need to do.
You cannot expect anyone to spoon feed you. We are here to help people who try to do something but run into problems. Not people who doesnt even try to understand what they do. The guides by vogella are very simple and there is no problem with the guide. You cannot simply copy paste the codes from the tutorial and expect it to compile and work.
vijai2011 said:
You cannot expect anyone to spoon feed you. We are here to help people who try to do something but run into problems. Not people who doesnt even try to understand what they do. The guides by vogella are very simple and there is no problem with the guide. You cannot simply copy paste the codes from the tutorial and expect it to compile and work.
Click to expand...
Click to collapse
i didn't find my answer on that website
nnnn1111 said:
i didn't find my answer on that website
Click to expand...
Click to collapse
Then it may mean that you dont know what you are searching for! Because the tutorial is all about what you need - ListView!
I just discovered how to use the action bar to have a OptionsMenu. I just solved a problem with it and I wanted to know if I did it the right way.
What I did
So, I added the menu to a fragment started by an activity, adding to it the setHasOptionsMenu(true) in the onCreate method and setting up the two convenience methods public void onCreateOptionsMenu() and public boolean onOptionsItemSelected() of course setting up the xml first.
The problem
Now, if I rotate my device in landscape mode the button in the action bar duplicates. If I put it in portrait mode again, the number of items stays the same (I'm sure it doesn't actually increase, checked the size in different ways) though.
What I thought and how I solved it
So, I was thinking about some fragment overlaps, but if they actually overlap then I shouldn't notice anything, right?
Is the menu being recreated, while not destroyed when the fragment is destroyed?
I solved the problem removing the item in the menu, in the Fragment.onDestroy() method manually.
Is the menu supposed to be cleared manually, or there is something wrong with my code (eg. fragments overlapping, etc..) ?
domenicop said:
Is the menu supposed to be cleared manually, or there is something wrong with my code (eg. fragments overlapping, etc..) ?
Click to expand...
Click to collapse
Could you please post your code? That would make helping much easier.
nikwen said:
Could you please post your code? That would make helping much easier.
Click to expand...
Click to collapse
Of course. Thanks for the interest.
This is the onCreate method of MainActivity.java, from where I handle the arrangement of fragments on the screen.
Also, place check my comment under the line "Log.d(TAG, "Orientation Portrait detected.");", where I try to explain why I handle fragments in that specific way. It's the way I understood it, but I'm not sure if that's correct.
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that goes all right, we have our fragment.
// Else, null will be returned.
mContactListFragment = (ContactListFragment) fm.findFragmentById(R.id.portraitFragmentContainer);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.replace(R.id.portraitFragmentContainer, mContactListFragment)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentById(R.id.landscapeFragmentContainer);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentById(R.id.contactsPagerFragmentContainer);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.replace(R.id.contactListFragmentContainer, mContactListFragment)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.replace(R.id.contactsPagerFragmentContainer, mContactsPagerFragment)
.commit();
}
}
}
This are the relevant pieces of the ContactListFragment.java, that have something to do with the menu
Note that I changed the way I checked for double menu entries.
Now I check if (menu.size() != 1), because I have just one item in there.
If I remove that clause, there will be two item in the menu after rotating to landscape mode, and if I take the device back to portrait mode, the two items will remain two. That's so even if I change from landscape to portrait and vice versa a hundred times from now, the menu items will always be two.
Code:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
Bundle args = getArguments();
mDatabase = (ContactsDatabase) args.getSerializable(DATABASE);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
if (menu.size() != 1) {
inflater.inflate(R.menu.contact_list_fragment_menu, menu);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addContactMenu:
mCallback.onAddContactMenuOptionSelected();
default:
return super.onOptionsItemSelected(item);
}
}
domenicop said:
I just discovered how to use the action bar to have a OptionsMenu. I just solved a problem with it and I wanted to know if I did it the right way.
What I did
So, I added the menu to a fragment started by an activity, adding to it the setHasOptionsMenu(true) in the onCreate method and setting up the two convenience methods public void onCreateOptionsMenu() and public boolean onOptionsItemSelected() of course setting up the xml first.
The problem
Now, if I rotate my device in landscape mode the button in the action bar duplicates. If I put it in portrait mode again, the number of items stays the same (I'm sure it doesn't actually increase, checked the size in different ways) though.
What I thought and how I solved it
So, I was thinking about some fragment overlaps, but if they actually overlap then I shouldn't notice anything, right?
Is the menu being recreated, while not destroyed when the fragment is destroyed?
I solved the problem removing the item in the menu, in the Fragment.onDestroy() method manually.
Is the menu supposed to be cleared manually, or there is something wrong with my code (eg. fragments overlapping, etc..) ?
Click to expand...
Click to collapse
I agree with nikwen but broadly the idea is...
- the menu belongs to the Activity not the Fragment.
- for an Activity for which you'd like an options menu you override onCreateOptionsMenu and do 2 things...
1/ call menu.add(...) for each menu item
2/ return 'true' at the end, so that your menu can be displayed
Also, see the Activity docs for onCreateOptionsMenu()
"This is only called once, the first time the options menu is displayed.
To update the menu every time it is displayed, see onPrepareOptionsMenu(Menu)."
If you want to add menu options to the Activity menu from within a Fragment you can also..
- override setHasOptionsMenu() in Fragment to return true
- override onCreateOptionsMenu() to add any items you like (just like you did at the Activity level)
- override onDestroyOptionsMenu()
The key thing here is that onCreateOptionsMenu() in Fragment is adding to the Activity menu.
It's hard to see without debugging exactly what's going on here but watch for calls to all of the above methods in Activity and Fragment and that will probably tell you what's going on.
If it is possible to control all menu options at the Activity level instead of the Fragment level, I would do that.
If not, and you need to use the Fragment menu methods, beware of Android's Fragment management (saving / restoring state)
Also, make sure your Fragments have an ID and/or tag.
(from the docs..)
"The fragment being instantiated must have some kind of unique identifier so that it can be re-associated with a previous instance if the parent activity needs to be destroyed and recreated. This can be provided these ways:
If nothing is explicitly supplied, the view ID of the container will be used.
android:tag can be used in <fragment> to provide a specific tag name for the fragment.
android:id can be used in <fragment> to provide a specific identifier for the fragment."
Finally, if all else fails, using Menu's findItem() before calling add() would be a safeguard, I suppose.
---------- Post added at 10:14 PM ---------- Previous post was at 09:52 PM ----------
domenicop said:
Of course. Thanks for the interest.
Click to expand...
Click to collapse
Sorry caught in the crossfire - have only just seen your code.
I think much of the above applies.
Set the menu up in the Activity instead of the Fragment, if you can.
I would also consider using layout-port and layout-land to control your two different layouts.
PicomatStudios said:
I agree with nikwen but broadly the idea is...
- the menu belongs to the Activity not the Fragment.
- for an Activity for which you'd like an options menu you override onCreateOptionsMenu and do 2 things...
1/ call menu.add(...) for each menu item
2/ return 'true' at the end, so that your menu can be displayed
Also, see the Activity docs for onCreateOptionsMenu()
"This is only called once, the first time the options menu is displayed.
To update the menu every time it is displayed, see onPrepareOptionsMenu(Menu)."
If you want to add menu options to the Activity menu from within a Fragment you can also..
- override setHasOptionsMenu() in Fragment to return true
- override onCreateOptionsMenu() to add any items you like (just like you did at the Activity level)
- override onDestroyOptionsMenu()
The key thing here is that onCreateOptionsMenu() in Fragment is adding to the Activity menu.
It's hard to see without debugging exactly what's going on here but watch for calls to all of the above methods in Activity and Fragment and that will probably tell you what's going on.
If it is possible to control all menu options at the Activity level instead of the Fragment level, I would do that.
If not, and you need to use the Fragment menu methods, beware of Android's Fragment management (saving / restoring state)
Also, make sure your Fragments have an ID and/or tag.
(from the docs..)
"The fragment being instantiated must have some kind of unique identifier so that it can be re-associated with a previous instance if the parent activity needs to be destroyed and recreated. This can be provided these ways:
If nothing is explicitly supplied, the view ID of the container will be used.
android:tag can be used in <fragment> to provide a specific tag name for the fragment.
android:id can be used in <fragment> to provide a specific identifier for the fragment."
Finally, if all else fails, using Menu's findItem() before calling add() would be a safeguard, I suppose.
---------- Post added at 10:14 PM ---------- Previous post was at 09:52 PM ----------
Sorry caught in the crossfire - have only just seen your code.
I think much of the above applies.
Set the menu up in the Activity instead of the Fragment, if you can.
I would also consider using layout-port and layout-land to control your two different layouts.
Click to expand...
Click to collapse
Wow. thanks for that detailed answer. :good: (Why have I used all my thanks?)
I've always put it into the Activity as well but it might make sense to add it to the Fragment sometimes. For example if you need the same Fragment in multiple Activities...
In that case you'd need to add a listener to the item in the Fragment method though.
@PicomatStudio Thank you for the detailed answer, I really appreciate that =)
Now I'm creating the menu in the activity and I don't have to worry about the fragments life cycle anymore.
The only problem is: I didn't get the menuInflater for free here, I guess it's because of the fact that in the Fragment scenario, I had to use the Activity inflater, whereas here in the activity, I can get my own, with getMenuInflater().
Here's the way I modified it, now is in MainActivity.java.
Please report back if you find something strange
Code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getSupportFragmentManager().findFragmentByTag(CONTACT_LIST_FRAGMENT) != null)
getMenuInflater().inflate(R.menu.contact_list_fragment_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addContactMenu:
onAddContactMenuOptionSelected();
default:
return super.onOptionsItemSelected(item);
}
}
domenicop said:
@PicomatStudio Thank you for the detailed answer, I really appreciate that =)
Now I'm creating the menu in the activity and I don't have to worry about the fragments life cycle anymore.
The only problem is: I didn't get the menuInflater for free here, I guess it's because of the fact that in the Fragment scenario, I had to use the Activity inflater, whereas here in the activity, I can get my own, with getMenuInflater().
Here's the way I modified it, now is in MainActivity.java.
Please report back if you find something strange
Code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getSupportFragmentManager().findFragmentByTag(CONTACT_LIST_FRAGMENT) != null)
getMenuInflater().inflate(R.menu.contact_list_fragment_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addContactMenu:
onAddContactMenuOptionSelected();
default:
return super.onOptionsItemSelected(item);
}
}
Click to expand...
Click to collapse
I don't tend to use MenuInflater (just menu.add()..)
But looking at the docs it takes a Context so could you do..
Code:
new MenuInflater(this);
.. from your Activity ?
On a general design point the less your Activity depends on its Fragments the better, I reckon.
domenicop said:
The only problem is: I didn't get the menuInflater for free here, I guess it's because of the fact that in the Fragment scenario, I had to use the Activity inflater, whereas here in the activity, I can get my own, with getMenuInflater().
Click to expand...
Click to collapse
Well, you can get one:
Code:
getActivity().getMenuInflater();
You are new to java development and want to get buttons working?
Maybe you are a Pro but want a reminder?
whatever you are this Guide is to help you to make buttons/check boxes...etc working and functional
Some people are distracted between guides over internet and want the easiest way to get their project working, me too
Steps :
1-Define the button :
Code:
Button btn1;
Checkbox chkbox1;
RadioButton radio1;
2- Intialize it :
Code:
btn1 = (Button) findViewById(R.id.btn1);
chkbox1= (Checkbox ) findViewById(R.id.chkbox1);
radio1= (RadioButton) findViewById(R.id.radio1);
3-Add the listener :
Button:
Code:
btn1.setOnClickListener(new OnClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onClick(View arg0) {
//Write awesome code here
}
});
CheckBox :
Code:
chkbox1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (start.isChecked()) {
//if the checkbox checked
} else {
//if not checked
}
}
});
}
radio button:
Code:
public void onRadioButtonClicked(View view) {
boolean checked = ((RadioButton) view).isChecked();
switch(view.getId()) {
case R.id.radio1:
if (checked){
}
else{
}
break;
}
}
or use it in a radio Group :
Code:
public void onRadioButtonClicked(View view) {
// Is the button now checked?
boolean checked = ((RadioButton) view).isChecked();
// Check which radio button was clicked
switch(view.getId()) {
case R.id.radio1:
if (checked)
//Write code
break;
case R.id.radio2:
if (checked)
//Write code
break;
}
}
Also insted of this you can use a onCheckedChanged for a radio button (Thanks for GalaxyInABox)
Code:
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (radioGroup.getCheckedRadioButtonId()) {
//Code
}
}
____________________________________________________________________
____________________________________________________________________
Also you can implement a Onclicklistener for the whole class to save resources : (thanks for @Jonny )
after defining and initializing your objects add this :
Code:
OnClickListener click_listener = new OnClickListener() {
public void onClick(View view) {
int id = view.getId();
if (id == your_id) {
//do stuff for this object
} else if (id == your_id2) {
//do other stuff for diffrent object
} else if (id == your_id3) {
//and so on
}
}
};
To do list :
-add on touch listeners
-add on drag listeners
Note : you can add a click listener to almost any thing (Textview or imageView or even EditText) just using the same method of adding listener to button
also there is some other ways to add a listener but this is the fastest and less disturbing :good:
If this guide is useful, press thanks
@ OP
CheckBox and RadioButtons don't they provide a CheckedChangeListener ?
Sent from my GT-S5302 using Tapatalk 2
sak-venom1997 said:
@ OP
CheckBox and RadioButtons don't they provide a CheckedChangeListener ?
Click to expand...
Click to collapse
Yes, and now you can use
Code:
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (radioGroup.getCheckedRadioButtonId()) {
//Code
}
}
to get the checked button. They are pretty much the same, but you can use view.getTag() easier in the first one.
And @mohamedrashad please show how to put the listener into a inner class. Many people don't know/use it, but it's that useful!
GalaxyInABox said:
Yes, and now you can use
Code:
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (radioGroup.getCheckedRadioButtonId()) {
//Code
}
}
to get the checked button. They are pretty much the same, but you can use view.getTag() easier in the first one.
Click to expand...
Click to collapse
I meant that the op shuld edit this guide and use those instead of OnCickListeners
GalaxyInABox said:
And @mohamedrashad please show how to put the listener into a inner class. Many people don't know/use it, but it's that useful!
Click to expand...
Click to collapse
ya new with java8 it will be a nice usage scenario of lambadas
Sent from my GT-S5302 using Tapatalk 2
GalaxyInABox said:
Yes, and now you can use
Code:
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (radioGroup.getCheckedRadioButtonId()) {
//Code
}
}
to get the checked button. They are pretty much the same, but you can use view.getTag() easier in the first one.
And @mohamedrashad please show how to put the listener into a inner class. Many people don't know/use it, but it's that useful!
Click to expand...
Click to collapse
sak-venom1997 said:
@ OP
CheckBox and RadioButtons don't they provide a CheckedChangeListener ?
Sent from my GT-S5302 using Tapatalk 2
Click to expand...
Click to collapse
ok, i will add this
You can also add onClick property in XML and then handle it in a code.
Awesome tutorial! Thank you very much!
Please, you could share more related knowledge. It's really useful!
Also, an activity can be a listener. In this case:
MyActivity implements onClickListener {
btn1.setOnClickListener(this);
public void onClick (View v) {
//your code
}
}
For this kind of stuff, using some well known libraries from well known Android dev is a must.
https://github.com/JakeWharton/butterknife
Very powerfull, super easy to use, error prone and without any performance impact.
rafalniski said:
You can also add onClick property in XML and then handle it in a code.
Click to expand...
Click to collapse
SKAm69 said:
Also, an activity can be a listener. In this case:
MyActivity implements onClickListener {
btn1.setOnClickListener(this);
public void onClick (View v) {
//your code
}
}
Click to expand...
Click to collapse
will add them both, although I don't like this way
Mohamedrashad. Thanks a lot.
Sent from my P880 using Tapatalk
If you have multiple clickable objects then it's best to use just 1 onClickListener for all of them and use a switch on their ID's. This reduces resource usage as you only have 1 listener, not 5, 10 or however many you would have otherwise. It's not essential for this but it is a best practice if you want to streamline your code.
Mobile right now so I can't chuck up an example until tomorrow evening or so.
You dude had a great thread. Its helping me. Bravoo !!
Sent from my GT-I8190 using XDA Premium 4 mobile app
As @Jonny already pointed out: Use your class as a listener instead of creating a new (anonymous) inner class! Say you have a ListView, instead of doing this:
Code:
class MyFragment extends Fragment {
private void someMethod() {
((ListView) getView().findViewById(R.id.someListView)).setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Code...
}
});
}
}
you can do this:
Code:
class MyFragment extends ListFragment implements AdapterView.OnItemClickListener, View.OnClickListener {
private void someMethod() {
((ListView) getView().findViewById(R.id.someListView)).setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Code...
}
}
This may look stupid, but when you have many listeners, you can un-clutter it. In my opinion this is the best way. You can also add "this" class as listener for as many ui elements as you want(because all of them extend view, you can use one OnClickListener), then you only need to have a switch statement to distinguish between the views. And voila, you prevented cluttering the code with boilerplate stuff.
Example using code in an app I'm making - app for my school.
Code:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Some code here for view/layouts etc
websitebutton = (Button) view.findViewById(R.id.website_btn);
facebookbutton = (Button) view.findViewById(R.id.facebook_btn);
twitterbutton = (Button) view.findViewById(R.id.twitter_btn);
websitebutton.setOnClickListener(handler);
facebookbutton.setOnClickListener(handler);
twitterbutton.setOnClickListener(handler);
return view;
}
OnClickListener handler = new OnClickListener() {
public void onClick(View view) {
switch (view.getId()) {
case R.id.website_btn :
Uri website = Uri.parse("http://wirralgrammarboys.com/");
Intent websiteintent = new Intent(Intent.ACTION_VIEW, website);
startActivity(websiteintent);
break;
case R.id.facebook_btn :
Uri facebook = Uri.parse("https://www.facebook.com/WirralGSB");
Intent facebookintent = new Intent(Intent.ACTION_VIEW, facebook);
startActivity(facebookintent);
break;
case R.id.twitter_btn :
Uri twitter = Uri.parse("https://twitter.com/WGSB");
Intent twitterintent = new Intent(Intent.ACTION_VIEW, twitter);
startActivity(twitterintent);
break;
}
}
};
Jonny said:
Example using code in an app I'm making.
Code:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Some code here for view/layouts etc
websitebutton = (Button) view.findViewById(R.id.website_btn);
facebookbutton = (Button) view.findViewById(R.id.facebook_btn);
twitterbutton = (Button) view.findViewById(R.id.twitter_btn);
websitebutton.setOnClickListener(handler);
facebookbutton.setOnClickListener(handler);
twitterbutton.setOnClickListener(handler);
return view;
}
OnClickListener handler = new OnClickListener() {
public void onClick(View view) {
int id = view.getId();
if (id == R.id.website_btn) {
Uri website = Uri.parse("http://wirralgrammarboys.com/");
Intent websiteintent = new Intent(Intent.ACTION_VIEW, website);
startActivity(websiteintent);
} else if (id == R.id.facebook_btn) {
Uri facebook = Uri.parse("https://www.facebook.com/WirralGSB");
Intent facebookintent = new Intent(Intent.ACTION_VIEW, facebook);
startActivity(facebookintent);
} else if (id == R.id.twitter_btn) {
Uri twitter = Uri.parse("https://twitter.com/WGSB");
Intent twitterintent = new Intent(Intent.ACTION_VIEW, twitter);
startActivity(twitterintent);
}
}
};
Click to expand...
Click to collapse
i'm adding this to OP if you don't mind jonny
mohamedrashad said:
i'm adding this to OP if you don't mind jonny
Click to expand...
Click to collapse
That's fine - if I didn't want people to use/adapt/learn from the code then I wouldn't put it up, use it as you want :good:
Sent from my HTC One using Tapatalk
Keep it up
Great tutorials, keep em coming!
Hey what about starting a new activity with onClickListiner
Sent from my M3S_D7 using XDA Free mobile app
---------- Post added at 03:57 PM ---------- Previous post was at 03:49 PM ----------
Hey and do u mind sending a source codes.zip file
Sent from my M3S_D7 using XDA Free mobile app
Rebound.co said:
Hey what about starting a new activity with onClickListiner
Sent from my M3S_D7 using XDA Free mobile app
---------- Post added at 03:57 PM ---------- Previous post was at 03:49 PM ----------
Hey and do u mind sending a source codes.zip file
Sent from my M3S_D7 using XDA Free mobile app
Click to expand...
Click to collapse
in the onClick method just have this code:
Code:
startActivity(new Intent(this, YourActivity.class));