I have an android tabhost with a listview inside, when I click on a listviewitem I want to show a new list at the place of the old list inside the tablayout.
How can I implement this? (I need to use listviews not fragments)
Thanks!
I found a solution: I put an activitygroup inside the tabhost, like so:
public class DrillDownWrapper extends ActivityGroup {
private ArrayList<View> history;
public static DrillDownWrapper group;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
history = new ArrayList<View>();
group = this;
//put the first listactivity
Intent i = new Intent(DrillDownWrapper.this, ListActivity.class);
View view = getLocalActivityManager().startActivity("ListActivity", i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
replaceView(view);
}
public void replaceView(View v) {
history.add(v);
setContentView(v);
}
public void back() {
if(history.size() > 1) {
history.remove(history.size()-1);
setContentView(history.get(history.size()-1));
} else {
finish();
}
}
#Override
public void onBackPressed() {
DrillDownWrapper.group.back();
return;
}
}
inside the listactivity you can get the context (ie to show a dialog) by calling getParent() method
Related
I am developing android application which having multiple tabs.
Now in launcher activity tabs display perfectly and can navigate through the tabs.
but if i call activity(which i wanted to show as Tab) on Button Clicked then tabs seems disappear.
please refer the given code and let me know if i am doing something wrong.
This is Main TabActivity
public class MyTabActivity extends TabActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
TabHost tabHost=getTabHost();
TabSpec deshTab=tabHost.newTabSpec("Deshboard");
deshTab.setIndicator("Deshboard");
Intent DeshboardIntent=new Intent(this,DeshboardActivity.class);
deshTab.setContent(DeshboardIntent);
tabHost.addTab(deshTab);
TabSpec clientTab=tabHost.newTabSpec("client");
clientTab.setIndicator("client");
Intent intent=new Intent(this,ClientActivity.class);
clientTab.setContent(intent);
tabHost.addTab(clientTab);
}
}
Now i wanted to start client activity like
void onButtonClick(View view)
{
int id = view.getId();
switch(id)
{
case R.id.client_btn:
Intent clientIntent = new Intent(DeshboardActivity.this,ClientActivity.class);
startActivity(clientIntent);
break;
}
}
but when i click this button it starts new activity but NOT in tab.
what should i do to display this activity in tab on button click also.?
Below code is ClientActivity which i wanted to display as TAB.
public class ClientActivity extends Activity
{
private DatabaseHandler dbHandler;
private ListView clientListView ;
private BaseAdapter listAdapter;
TabHost tabHost;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.clientactivity);
dbHandler = new DatabaseHandler(this);
final List<Client> clientList = dbHandler.getAllclient();
clientListView = (ListView)findViewById(R.id.client_list);
listAdapter = new ClientListAdapter(this, clientList);
clientListView.setAdapter(listAdapter);
clientListView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
Client client = clientList.get(position);
Toast.makeText(getApplicationContext(), client.getFirstName(), Toast.LENGTH_LONG).show();
Intent clientInfoIntent = new Intent(getApplicationContext(), ClientInfoActivity.class);
clientInfoIntent.putExtra("client",client);
startActivity(clientInfoIntent);
//finish();
}
});
}
}
That's because your ClientActivity is launched on top of your TabActivity. That way your tabbar is not shown anymore.
I suggest you use fragments for your ClientActivity.
A tutorial how to use fragments:
http://developer.android.com/guide/components/fragments.html
I have a listview in my activity.
first time I click listview item, it works fine.
when I press back button and comes back to this activity, I can't click on the item anymore.
this listview works fine with android2.
when i test with android 4, happens this problem.
I found this kind of problem here, and I've tried all 'descendentFocusabilty' thing,
but not solved yet.
I know i shouldn't post almost same question. but i couldn't find any answer works fine there.
please help me solve this problem.
here is my child1 activity
public class TabChild1 extends NavigationActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabchild1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
adapter.add("red");
adapter.add("green");
adapter.add("blue");
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
ListView listView = (ListView) parent;
String item = (String) listView.getItemAtPosition(position);
Intent intent = new Intent(TabChild1.this, TabChild2.class);
int iNum = position;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
goNextHistory("TabChild2", intent);
}
});
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
here is my NavigationActivity
public class NavigationActivity extends Activity {
public void goNextHistory(String id, Intent intent) {
NavigationGroupActivity parent = ((NavigationGroupActivity) getParent());
View view = parent.group.getLocalActivityManager()
.startActivity(id,intent)
.getDecorView();
parent.group.replaceView(view);
}
#Override
public void onBackPressed() {
NavigationGroupActivity parent = ((NavigationGroupActivity) getParent());
parent.back();
}
}
here is my NavigationGroupActivity
public class NavigationGroupActivity extends ActivityGroup {
ArrayList<View> history;
NavigationGroupActivity group;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
history = new ArrayList<View>();
group = this;
}
public void changeView(View v) {
history.remove(history.size() - 1);
history.add(v);
setContentView(v);
}
public void replaceView(View v) {
history.add(v);
setContentView(v);
}
public void back() {
if(history.size() > 1) {
history.remove(history.size() - 1);
setContentView(history.get(history.size() - 1));
} else {
finish();
}
}
#Override
public void onBackPressed() {
group.back();
return;
}
}
and my child1 layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
i think You have to use finish() inside the onBackPressed() method of class TabChild1. and comment the line parent.back() inside the onBackPressed() method of class NavigationActivity.
I think this will work for you.
I'm new in Android development and I wanted to make application that has header, body and footer and by clicking on one of the buttons in footer some layout will be loaded into body. I used some kind of "MasterPage" as described here.
When the button is pressed neither new_exercise layout nor exercises layout is loaded. Why? Maybe instead of all of this I should use any kind of tabs? Or maybe I can't inflate layout and should create new activity?
Here the code of the BaseActivity and NewExercise activity:
public class BaseActivity extends Activity{
LinearLayout linBaseBody;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.base_layout);
linBaseBody = (LinearLayout)findViewById(R.id.base_body);
initButtons();
}
#Override
public void setContentView(int id) {
LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(id, linBaseBody);
}
private void initButtons()
{
Button btn1 = (Button) findViewById(R.id.newEx);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setContentView(R.layout.new_exercise);
}
});
Button btn2 = (Button) findViewById(R.id.showAllEx);
btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setContentView(R.layout.exercises);
}
});
}
public class NewExercise extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.new_exercise);
}
}
public class Exercises extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exercises);
}
}
How your code is written, it would make more sense to use a new Activity. However, If you wanted to keep all of the view in one Activity, you could walk through all of your layouts calling mLayout.setVisible(View.VISIBLE); or you could use ViewStubs.
As to answer your question, why, what you are doing is adding the view (and their layouts) directly to your already created and inflated content view (the one you created in onCreate). You will need to clear the Activities contentView first to see the changes you are making with the button.
i am new to Android and i am facing a problem in calling different activities from the same screen with same user interface.
Actually i want to implement d functionality of a tab activity but instead of tabs i am providing buttons and the buttons should act like tabs.
I am unable to do that. I am going wrong some where.
Can anyone help me please.....
HomeScreen class is:
public class HomeScreen extends Activity implements OnItemClickListener {
public Integer[] images = { R.raw.mobile, R.raw.note_books, R.raw.ac,
R.raw.drivers, R.raw.camera, R.raw.home_theaters, R.raw.pda,
R.raw.tv, R.raw.washing_machines, R.raw.scanners };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid);
GridView gv = (GridView) findViewById(R.id.gridV);
LayoutInflater inflater = getLayoutInflater();
gv.setAdapter(new GridViewAdapter(images, inflater));
gv.setOnItemClickListener(this);
if (StaticUtils.scheckStatus){
parseData();
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent contents = new Intent(HomeScreen.this, Cat.class);
contents.putExtra("homescreen", arg2);
startActivity(contents);
}
Cat.class is this:
class Cat extends Activity implements OnClickListener{
private Button mBtnContents, mBtnBrand, mBtnCategory, mBtnBack;
#Override
public void onCreate(Bundle si){
super.onCreate(si);
setContentView(R.layout.gridtab);
int i = getIntent().getIntExtra("homescreen", 0);
mBtnContents=(Button) findViewById(R.id.btnContents);
mBtnContents.setOnClickListener(this);
mBtnBrand=(Button) findViewById(R.id.btnBrand);
mBtnBrand.setOnClickListener(this);
mBtnCategory=(Button) findViewById(R.id.btnCategory);
mBtnCategory.setOnClickListener(this);
mBtnBack=(Button) findViewById(R.id.btnBack);
mBtnBack.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v==mBtnContents){
int i = getIntent().getIntExtra("homescreen", 0);
Intent in=new Intent(Cat.this, Pc.class);
in.putExtra("homescreen", i);
startActivity(in);
} else if(v==mBtnBrand){
startActivity(new Intent(Cat.this, Sd.class));
} else if(v==mBtnCategory){
startActivity(new Intent(Cat.this, Sbc.class));
} else if(v==mBtnBack){
startActivity(new Intent(Cat.this, Hs.class));
}
}
}
When i click on contents button its displaying the details but when i click on the other buttons its not showing anythng
Instead of "v==mBtnContents" use "v.equals(mBtnContents)" because View is an object.
I am trying to figure out the best practice of communication between a TabActivity and the child activity embedded in this TabActivity.
In my TabActivity, there is a button. When the button is clicked, I want the child activity embedded in this TabActivity to be updated. I wrote the code like below, and just wonder whether it is a good practice. Thanks.
MyTabActivity.java
public class MyTabActivity extends TabActivity implements OnClickListener {
private TabHost m_tabHost;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ff_tab_activity);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
m_tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;
intent = new Intent().setClass(this, ChildActivity.class);
spec = m_tabHost.newTabSpec("Tab 1");
spec.setContent(intent);
tabView = (TextView) inflater.inflate(R.layout.tab_indicator, null);
spec.setIndicator(tabView);
m_tabHost.addTab(spec);
m_tabHost.setCurrentTab(0);
ImageView nextButtonIv = (ImageView) findViewById(R.id.next_button);
nextButtonIv.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.next_button:
synchronized (ChildActivity.class) {
if (null != ChildActivity.s_childActivity) {
ChildActivity.s_childActivity.changeUI();
}
}
break;
}
}
ChildActivity.java
public class ChildActivity extends Activity {
public static ChildActivity s_childActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
synchronized (MatchupsActivity.class) {
s_childActivity = this;
}
setContentView(R.layout.child_activity);
}
public void changeUi() {
code that changes UI
}
protected void onDestroy() {
super.onDestroy();
synchronized (MatchupsActivity.class) {
s_childActivity = null;
}
}
Since TabActivity is an ActivityGroup, I would use one of the following:
getCurrentActivity()
Returns the child tab activity being displayed. In your case, this method will return the instance of ChildActivity being used.
ChildActivity childActivity = (ChildActivity) getCurrentActivity();
getLocalActivityManager().getActivity(String)
Returns the child tab activity given its ID/tab spec name, whatever activity being displayed.
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
I suggest overriding onNewIntent(Intent) in your ChildActivity:
Intent intent = new Intent();
intent.putExtra("xyz", "whatever"); // or a serializable
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
childActivity.onNewIntent(intent);
Let me know if it works!
Seems fine. A couple of notes:
- I see no reason for synchronization.
- I'd replace
ChildActivity.s_childActivity.changeUI();
with
if(ChildActivity.s_childActivity != null){
ChildActivity.s_childActivity.changeUI();
}
or even
try{
ChildActivity.s_childActivity.changeUI();
} catch(Exception e){
//log
}
for added paranoid safety. :)
The way above with
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
childActivity.onNewIntent(intent);
is not very nice. Instead of invoking your activity method directly (it can be null!!!) better do it this way:
Intent intent = new Intent(this, ChildActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(AlbumBrowser.INTENT_EXTRA_FILTER, mediaTitle);
getLocalActivityManager().startActivity("activityIdHere", intent);
Couple of design issues with this, but overall it seems reasonable.
I would forgo the static instance in the ChildActivity class. Why? Well, think about the relationship you're modeling. A TabActivity has a ChildActivity. This is textbook composition, and would be accomplished by adding a ChildActivity field to the TabActivity class, like so:
public class TabActivity {
private ChildActivity child;
//remember to initialize child in onCreate
//then, call methods using child.changeUI();, for example
}
This is better, because A) now I can have multiple instances of TabActivity and ChildActivity that won't interfere with each other (before, it was just a static variable, so only one ChildActivity could be used), and B) the ChildActivity is encapsulated inside the TabActivity class... before, it was a public field, meaning anything can use and modify it (might not be desirable; can often lead to some strange runtime bugs as well as messy, tied-together code) - we changed it to a private field, because we don't really want other classes accessing it in unexpected ways.
The only thing you may need access to from the ChildActivity is the parent (TabActivity). To do this, add the following methods and field to the ChildActivity class, and call the registerParent() method after constructing the ChildActivity:
public class ChildActivity ...{
private TabActivity parent;
public void registerParent(TabActivity newParent){
if (newParent != null){
parent = newParent;
}
}
}
So, if you need access to the parent TabActivity from the child, just call parent.someMethod();
It would also be wise to access fields like parent and child through getters and setters; it might save you some time in the long run.
You can use getParent() to obviate the need to do any of this.
Here's my launcher child class with buttons that switch between activities handled by the tabHost:
public class LaunchPadActivity extends Activity implements OnClickListener {
private static final int ICON_PROFILE = 0;
private static final int ICON_SEARCH = 1;
private static final int ICON_MAP = 2;
private static final int FAVOURITES = 3;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.launchpad);
GridView launchPad = (GridView) findViewById(R.id.launchpad);
launchPad.setAdapter(new LaunchIconAdapter(this));
}
public class LaunchIconAdapter extends BaseAdapter {
private Context mContext;
// references to our images
private Integer[] mThumbIds = { R.drawable.user, R.drawable.find,
R.drawable.map, R.drawable.favourites, R.drawable.reviews,
R.drawable.news, R.drawable.tutorial, R.drawable.info,
R.drawable.options, };
public String[] texts = { "Profile", "Search", "Map", "Favourites",
"Reviews", "News", "Tutorial", "Info", "Options" };
public LaunchIconAdapter(Context c) {
mContext = c;
}
// Number of thumbs determines number of GridView items
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
// Icon elements
LinearLayout launchIcon;
ImageView launchImage;
TextView launchText;
if (convertView == null) {
launchIcon = (LinearLayout) ((LayoutInflater) mContext
.getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(
R.layout.launchicon, null);
} else {
launchIcon = (LinearLayout) convertView;
}
// Add ClickListener with metadata
launchIcon.setTag(new Integer(position));
launchIcon.setOnClickListener(LaunchPadActivity.this);
// Get subviews
launchImage = (ImageView) launchIcon
.findViewById(R.id.launch_image);
launchText = (TextView) launchIcon.findViewById(R.id.launch_text);
// Configure subviews
launchImage.setImageResource(mThumbIds[position]);
launchText.setText(texts[position]);
return launchIcon;
}
}
#Override
public void onClick(View v) {
int position = ((Integer) v.getTag()).intValue();
switch (position) {
case ICON_PROFILE:
Toast.makeText(this, "Profile", Toast.LENGTH_LONG).show();
break;
case ICON_SEARCH:
Toast.makeText(this, "Search", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(1);
break;
case ICON_MAP:
Toast.makeText(this, "Map", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(2);
break;
case FAVOURITES:
Toast.makeText(this, "Map", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(3);
break;
}
}
}
Works like a charm.