I am trying to convert my entire project from using ActivityGroups to using Fragments.
Here is my old code :
SettingsActivityGroup
public class SettingsActivityGroup extends ActivityGroup
{
// Keep this in a static variable to make it accessible for all the nested activities, lets them manipulate the view
public static SettingsActivityGroup group;
// Need to keep track of the history if you want the back-button to work properly, don't use this if your activities requires a lot of memory.
private ArrayList<View> history;
// Window focus changed listener
public OnActivityGroupViewChanged activityGroupViewChangedListener = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Allocate history
this.history = new ArrayList<View>();
// Set group
group = this;
// Start root (first) activity
Intent myIntent = new Intent(this, SettingsActivity.class); // Change to the first activity of your ActivityGroup
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
ReplaceView("SettingsActivity", myIntent);
}
SettingsActivity
public class SettingsActivity extends Activity
{
String[] settingsLabels = {"Viderestilling", "Voicemail", "Vis nummer",
"Kø styring", "Optag samtaler", "Services" };
ListView lv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
lv = (ListView) findViewById(R.id.SettingsLV);
lv.setTextFilterEnabled(true);
populateListView();
}
private void populateListView()
{
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.settings_items, R.id.settings_item_label, settingsLabels));
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
// SwitchActivity(position);
}
});
}
If I want to extend ListFragment instead of Activity - What do I need to change to make sure that everything still works ?
Have you looked at the Developer Guide article on Fragments? I think it very nearly describes your exact use case (an array-backed list in one fragment and the detail in another). And do check out the complete sample implementation in APIDemos. There's even a backward-compatible version in API 4+ Support Demos.
Related
I've got a class that should, theoretically, display RSS headlines, from a SINGLE RSS feed site, in a ListView called searchListView. If the ListView is empty a TextView appears informing the user that the ListView is empty, which is what happens every time I navigate to this activity. The button and EditText is for filtering the headlines.
I've got the exact same class in another project (this class is the main activity in said project) which works perfectly fine.
RssItem is a class that parses the RSS feed information into a headline title and URL to the headline.
Note: SearchActivity is not the main activity.
Edit: I'm using a CallBack and LoaderManager in the main activity to display items in a list view as well. I'm not too knowledgeable about these and I really don't know if they might be causing the issue due to the main activity. I do not pass any information from the main activity, though.
FIXED: I wasn't getting any errors or anything but, for some reason, nothing would get displayed. Then I went into the android manifest and realised that the app doesn't have permissions to connect to the internet. Silly mistake, easy to miss.
<uses-permission android:name="android.permission.INTERNET"/>
SearchActivity.java
public class SearchActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<RssItem>> {
private EditText mEditText;
private Button mButton;
private ArrayAdapter<RssItem> mAdapter;
private ListView mListView ;
// hard wire Rss feed source for the time being
private String mDataSource = "http://feeds.bbci.co.uk/news/uk/rss.xml";
// no search string at the moment
private String mSearchString = "";
private static final int LOADER_ID = 1;
// The callbacks through which we will interact with the LoaderManager.
private LoaderManager.LoaderCallbacks<List<RssItem>> mCallbacks;
private LoaderManager mLoaderManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mButton = (Button) findViewById(R.id.button);
mEditText = (EditText)findViewById(R.id.editTextSearch);
mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
mListView = (ListView)findViewById(R.id.searchListView);
mListView.setAdapter(mAdapter);
TextView emptyText = (TextView)findViewById(R.id.textViewEmpty);
mListView.setEmptyView(emptyText);
// Set list view item click listener
mListView.setOnItemClickListener(new ListListener(this));
// The Activity (which implements the LoaderCallbacks<Cursor>
// interface) is the callbacks object through which we will interact
// with the LoaderManager. The LoaderManager uses this object to
// instantiate the Loader and to notify the client when data is made
// available/unavailable.
mCallbacks = this;
// Initialize the Loader with id '1' and callbacks 'mCallbacks'.
// If the loader doesn't already exist, one is created. Otherwise,
// the already created Loader is reused. In either case, the
// LoaderManager will manage the Loader across the Activity/Fragment
// lifecycle, will receive any new loads once they have completed,
// and will report this new data back to the 'mCallbacks' object.
mLoaderManager = getLoaderManager();
mLoaderManager.initLoader(LOADER_ID, null, mCallbacks);
}
// handler for search button click
public void onClick(View v){
mSearchString = mEditText.getText().toString();
mLoaderManager.restartLoader(LOADER_ID, null, mCallbacks);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public Loader<List<RssItem>> onCreateLoader(int id, Bundle args) {
RssLoader loader = new RssLoader(
this, // context
mDataSource, // URL of Rss feed
mSearchString // search loaded RssItem for match in title
);
return loader;
}
#Override
public void onLoadFinished(Loader<List<RssItem>> loader, List<RssItem> data) {
mAdapter.clear();
mAdapter.addAll(data);
}
#Override
public void onLoaderReset(Loader<List<RssItem>> loader) {
mAdapter.clear();
}
}
ListListener.java
public class ListListener implements OnItemClickListener {
// And a reference to a calling activity
// Calling activity reference
Activity mParent;
/** We will set those references in our constructor.*/
public ListListener(Activity parent) {
mParent = parent;
}
/** Start a browser with url from the rss item.*/
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
// We create an Intent which is going to display data
Intent i = new Intent(Intent.ACTION_VIEW);
// We have to set data for our new Intent;
i.setData(Uri.parse(((RssItem)(parent.getItemAtPosition(pos))).getLink()));
// And start activity with our Intent
mParent.startActivity(i);
}
}
I wasn't getting any errors or anything but, for some reason, nothing would get displayed. Then I went into the android manifest and realised that the app doesn't have permissions to connect to the internet. Silly mistake, easy to miss.
<uses-permission android:name="android.permission.INTERNET"/> was missing.
I have a layout with a ListView and ImageView. Initially, ImageView is invisible. I have a list, when an Item is clicked, it shows the Image of that item by setting ImageView and making it visible and listView is invisible, so far everything is ok. From there, onBackPressed() I want to see my listview again, I override onBackPressed(), to make my image view invisible and listview visible. However, when I select an item and see the image of it then press back, a blank activity comes, not my listView. I don't want to call the activity again, what should I do? What is wrong about listView? I tried to call invalidate() and invalidateViews(), setting adapter again, but they aren't woring.
Actually I'm filing adapter in the onResume of the activity, here is the code:
public class MyViewActivity extends Activity{
ListView imageList;
CustomImageListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_list_view);
//initialization of image array list etc
}
#Override
public void onResume(){
super.onResume();
imageList = (ListView) findViewById(R.id.listView);
adapter = new CustomImageListAdapter(this,R.layout.image_item, imageNames);
imageList.setAdapter(adapter);
imageList.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> adapter, View view, int i,
long l) {
// TODO Auto-generated method stub
if(imageNames.get(i) != null) {
onImageSelected(i);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.image_list_view, menu);
return true;
}
public void onImageSelected(int position) {
...
}
#Override
public void onBackPressed() {
if (img.getVisibility() == ImageView.VISIBLE){
// img.setVisibility(ImageView.INVISIBLE);
// imageList.invalidateViews();
// imageList.setVisibility(ListView.VISIBLE);
// Here actually I want to use the upper part that I commented, but it didn't work, I have to call the same activity again to see my listview
Intent i = new Intent(MyViewActivity.this, MyViewActivity.class);
startActivity(i);
finish();
}
else {
....
}
return;
}
private class CustomImageListAdapter extends ArrayAdapter<String>{
...
}
As long as I can guess, the problem is caused by
img.setVisibility(ImageView.INVISIBLE);
You can try to use View.GONE instead.
The difference is clearly stated in android api's doc and I quoted:
/**
* This view is invisible, but it still takes up space for layout purposes.
*/
public static final int INVISIBLE = 0x00000004;
/**
* This view is invisible, and it doesn't take any space for layout
*/
public static final int GONE = 0x00000008;
By the way, I will recommend to use fragments to do your job. Specifically, a fragment A to present the listview, and when an item is clicked, switch to fragment B which contains the content. When Back is pressed, just let the backstack do its job.
Intent i = new Intent(MyViewActivity.this, MyViewActivity.class);
i.putExtra("currentObjectID",objectID);
startActivity(i);
finish();
Why are you traversing within the same activity? You should understand the use of intents ,If you want to stay within the same activity , Just set a flag for currentObjectID instead of put Extra..
Am developing an app where i need to call multiple ListFragments on same activity. It contains main parent ListFragment with 10 rows in it.
By clicking each row i need to open new child ListView next to parent ListView as like this. And my coding is
public class FragmentListArray extends Activity {
static String[] TITLES =
{
"Henry IV (1)",
"Henry V",
"Henry VIII",
"Richard II",
"Richard III",
"Merchant of Venice",
"Othello",
"King Lear"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the list fragment and add it as our sole content.
if (getFragmentManager().findFragmentById(android.R.id.content) == null) {
ArrayListFragment list = new ArrayListFragment();
getFragmentManager().beginTransaction().add(android.R.id.content, list).commit();
}
}
public static class ArrayListFragment extends ListFragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, FragmentListArray.TITLES));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// here i need to achieve my childview click listener..
}
}
}
I don't know how to set onitem click listener. Help me in achieving the above. Thanks in advance.
You can use getActivity() and cast the result to your activity's class to get instance of the Activity, which holds the fragment.
Define some function that will accept the id of the item, depending on which you need to load data in the sectond list Fragment. Should look like this:
YourActivity activity = (YourActivity)getActivity();
activity.fillSecondFragment(clickedItemId);
What you are trying to achieve it's very similiar to android developers example about fragments, instead a normal fragment when list item click use your listfragmnet (which in fact is a fragment)
http://developer.android.com/guide/components/fragments.html
I need to display a list of text items to the screen and make them clickable. So it would be something like a list of links on a web application.
How can I do that in an Android Activity screen?
It would be some random number of items that I have to pull from a db and display all as links.
Any idea how that can be done?
You should read the doc about ListActivity, ListView and follow the Hello ListView tutorial.
Yes you can do it. Create a DataExchange class to fetch it from Db..
Store the Strings in an Array.
Create a ArrayAdapter to display the array of Strings you got from the database.
for Example
public class AndroidListViewActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// storing string resources into Array
String[] numbers = {"one","two","three","four"}
// here you store the array of string you got from the database
// Binding Array to ListAdapter
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, numbers));
// refer the ArrayAdapter Document in developer.android.com
ListView lv = getListView();
// listening to single list item on click
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// selected item
String num = ((TextView) view).getText().toString();
// Launching new Activity on selecting single List Item
Intent i = new Intent(getApplicationContext(), SingleListItem.class);
// sending data to new activity
i.putExtra("number", num);
startActivity(i);
}
});
}
}
The secondActivity to display the Particular item you have clicked should be
public class SingleListItem extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.single_list_item_view);
TextView txtProduct = (TextView) findViewById(R.id.product_label);
Intent i = getIntent();
// getting attached intent data
String product = i.getStringExtra("number");
// displaying selected product name
txtProduct.setText(product);
}
}
you have to create various layout files accordingly..
Hope this helps you :)
You should use a ListView. It's very simple, just create a ListActivity, put your items inside an Adapter and then set it as the Adapter of your ListActivity.
You can read more about ListViews here
There is also a new paradigm called ListFragment.
I have used ListViews before but prefer the fragments approach now - it's just very straight forward and quite flexible esp on tablets since the interation with another area on the screen when selecting an item is quite flexible and only requires very little code.
Just one example:
public class Select_FoodCategories_Fragment extends android.app.ListFragment {
private static final boolean DEBUG = true;
#Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG)
Log.i(this.getClass().getSimpleName(), " ->"
+ Thread.currentThread().getStackTrace()[2].getMethodName());
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (DEBUG)
Log.i(this.getClass().getSimpleName(), " ->"
+ Thread.currentThread().getStackTrace()[2].getMethodName());
HoldingActivity a = (HoldingActivity) getActivity();
//accessing a variable of the activity is easy
a.visibleListViewInFragment = getListView();
List<XYZ> listTodisplay = a.getListToDisplay();
MyAdapter adapter = new MyAdapter(
getActivity(), 0, listTodisplay);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (DEBUG)
Log.i(this.getClass().getSimpleName(), " ->"
+ Thread.currentThread().getStackTrace()[2].getMethodName());
XYZ item = (XYZ) getListAdapter()
.getItem(position);
}
}
More info here: http://developer.android.com/reference/android/app/ListFragment.html
By the way, I find it really worth it to get familiar with the new fragments concept - it just makes live much easier - esp on tablets!
ps I left the debug statements in on purpose - since it helps alto to understand the whole concept much faster in my experience
i have made menu list containing play, settings, exit. but clicking the button doesn take me to the desired activity the listner is not working..can any one help me solve the problem.. will b thankfull..
yes its a list view control..
there are two errors in my code one is that
## The type new AdapterView.OnItemClickListener(){} must implement the inherited abstract method AdapterView.OnItemClickListener.onItemClick(AdapterView, View, int, long)## in LINE1
And the other one is ## View cannot be resolved to a type## in LINE 2
"Actually i want to shift from one screen to another when i click on the item in main menu screen"
Here is the code of main menu
public class MenuActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
ListView menuList = (ListView) findViewById(R.id.list);
String[] items = {
getResources().getString(R.string.pla),
getResources().getString(R.string.sco),
getResources().getString(R.string.set),
getResources().getString(R.string.hel),
getResources().getString(R.string.qui)
};
ArrayAdapter < String > adapt = new ArrayAdapter < String > (this, R.layout.menu_items, items);
menuList.setAdapter(adapt);
menuList.setOnItemClickListener(new AdapterView.OnItemClickListener() { //LINE 1 error
public void onItemClick(AdapterView <? > parent, View itemClicked, //LINE 2 error
int position, long id) {
TextView textView = (TextView) itemClicked;
String strText = textView.getText().toString();
if (strText.equalsIgnoreCase(getResources().getString(
R.string.pla))) {
// Game
startActivity(new Intent(MenuActivity.this,
GameActivity.class));
} else if (strText.equalsIgnoreCase(getResources().getString(
R.string.hel))) {
// Help
startActivity(new Intent(MenuActivity.this,
HelpActivity.class));
} else if (strText.equalsIgnoreCase(getResources().getString(
R.string.set))) {
//Settings
startActivity(new Intent(MenuActivity.this,
SettingsActivity.class));
} else if (strText.equalsIgnoreCase(getResources().getString(
R.string.sco))) {
// Scores
startActivity(new Intent(MenuActivity.this,
ScoresActivity.class));
}
}
});
}
}
ListView lv = ...;
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0,View arg1, int arg2, long arg3)
{
//Do Your Stuff
}
});
or you can make your custom adapter and write the button's click event
use intent
Intent play= new Intent(getApplicationContext(),Play.class);
startActivity(play);
there's lots of tutorial about menu
This task can be accomplished using one of the android's main building block named as Intents and One of the methods public void startActivity (Intent intent) which belongs to your Activity class.
An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested BroadcastReceiver components, and startService(Intent) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.
An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.
Refer the official docs -- http://developer.android.com/reference/android/content/Intent.html
public void startActivity (Intent intent) -- Used to launch a new activity.
So suppose you have two Activity class and on a button click's OnClickListener() you wanna move from one Activity to another then --
PresentActivity -- This is your current activity from which you want to go the second activity.
NextActivity -- This is your next Activity on which you want to move.
So the Intent would be like this
Intent(PresentActivity.this, NextActivity.class)
Finally this will be the complete code
public class PresentActivity extends Activity {
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.content_layout_id);
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
Intent activityChangeIntent = new Intent(PresentActivity.this, NextActivity.class);
// currentContext.startActivity(activityChangeIntent);
PresentActivity.this.startActivity(activityChangeIntent);
}
});
}
}
This exmple is related to button click you can use the code anywhere which is written inside button click's OnClickListener() at any place where you want to switch between your activities like in your setOnItemClickListener.