The Android Developers TabWidget tutorial says the following:
"You can implement your tab content in one of two ways: use the tabs to swap Views within the same Activity, or use the tabs to change between entirely separate activities."
The tutorial goes on to demonstrate how you can use tabs with separate Activities. I have been unable to find an example of using tabs with different Views within the same Activity. I would rather not re-invent this particular wheel, so I am hoping someone here knows how this is done and can clue me in. Thanks!
I think in the .setContent method of each tab you pass in the view you wish to use:
TabHost.TabSpec spec1 = tabs.newTabSpec("tag1");
spec1.setContent(R.id.AnalogClock01);
spec1.setIndicator("Analog Clock");
Here's an example I found awhile back:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabHost android:id="#+id/TabHost01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TabWidget android:id="#android:id/tabs" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<FrameLayout android:id="#android:id/tabcontent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="65px">
<AnalogClock android:id="#+id/AnalogClock01" android:layout_width="wrap_content" android:layout_height="wrap_content"></AnalogClock>
<DigitalClock android:text="DigitalClock01" android:id="#+id/DigitalClock01" android:layout_width="wrap_content" android:layout_height="wrap_content"></DigitalClock>
</FrameLayout>
</TabHost>
</LinearLayout>
And the Java code for this example is as follows:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;
public class tabexample extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabs = (TabHost)findViewById(R.id.TabHost01);
tabs.setup();
TabHost.TabSpec spec1 = tabs.newTabSpec("tag1");
spec1.setContent(R.id.AnalogClock01);
spec1.setIndicator("Analog Clock");
tabs.addTab(spec1);
TabHost.TabSpec spec2 = tabs.newTabSpec("tag2");
spec2.setContent(R.id.DigitalClock01);
spec2.setIndicator("Digital Clock");
tabs.addTab(spec2);
}
}
I used this one and it was fine for me
http://www.codeproject.com/Articles/107693/Tabbed-Applications-in-Android
Related
I have a button in my MainActivity that opens FragmentA. FragmentA covers the whole screen, but I still see the button from MainActivity, and I can still click on it.
I've tried using clickable in my fragment layout but it's not working
MainActivty
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val fragmentManager = this#MainActivity.supportFragmentManager
fragmentManager.beginTransaction()
.add(R.id.fragment_container, AFragment())
.addToBackStack(null)
.commit()
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="#+id/fragment_container">
<Button
android:text="Button Main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</android.support.constraint.ConstraintLayout>
fragment_a.xml
<?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:clickable="true"
android:focusable="true">
android:background="#color/colorPrimary"
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="A"/>
</LinearLayout>
This is happening because you placed your Button inside of the ConstraintLayout you're using as the container of your Fragment.
When you add a fragment into a container like what you're doing, it's simply adding it in the same manner as if it was a View.
Therefore, if you add a Fragment into a ConstraintLayout that already possesses a Button as a child, the Fragment will be shown alongside the Button due to ConstraintLayout allowing for overlapping Views.
This is also why, if your container was a LinearLayout, then adding a Fragment will place the fragment underneath your Button instead.
So, with that in mind, the solution would be to handle it as if they were Views.
If you added a View into a layout and you have another View overlapping, how would you get rid of it?
The most common solution would be to set the Button's visibility to INVISIBLE or GONE when the Fragment is added.
Another solution might be to raise the elevation of the Fragment, so it's now higher than your Button.
Of course, you may also remove the button from the Container and place it inside a Fragment too.
This way, you can use the replace() method in a FragmentManager to replace the Fragment containing your Button with the Fragment you want to show.
I am a beginner and I am asking this just to gain knowledge. so in my app, I have a MainActivity And its layout activity_main.xml.
here is the code of activity main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.testapp.myapp.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"
android:id="#+id/btn1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/btn1"
android:text="Button 2"
android:id="#+id/btn2"/> </RelativeLayout>
And here is the MainActivity.java
package com.testapp.myapp;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}}
I Have created Two Blank activities named By Button1PDF And Button2PDF And Each Has layout named button1_pdf.xml and button2_pdf.xml respectively.
So what i wanna do is, i want to set a pdf file against these New Activities and when I will click on btn1 or btn2 On MainActivity, I want it to display the new activity Button1PDF or Button2PDF activity which will be containing the pdfs.
I tried this online using webview and it works flawlessly. but now i want it to display offline(means complete offline)
i have done some research and i found some libraries like
compile 'com.github.barteksc:android-pdf-viewer:2.0.3'
but i don't know how to use it. hope someone can clear my doubts.
thanks.
You will need to download the files first and then display them to the user using that library.
Read this question on how to download file from internet
I have the following activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
TabHost mainTabHost = (TabHost) findViewById(R.id.mainTabHost);
mainTabHost.setup();
mainTabHost.addTab(mainTabHost.newTabSpec("Tab 1").setIndicator("", ContextCompat.getDrawable(this, R.drawable.d1)).setContent(new Intent(this, Activity1.class)));
mainTabHost.addTab(mainTabHost.newTabSpec("Tab 2").setIndicator("", ContextCompat.getDrawable(this, R.drawable.d2)).setContent(new Intent(this, Activity2.class)));
mainTabHost.addTab(mainTabHost.newTabSpec("Tab 3").setIndicator("", ContextCompat.getDrawable(this, R.drawable.d3)).setContent(new Intent(this, Activity3.class)));
}
}
And this is the XML
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#id/mainTabHost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activityHorizontalMargin"
android:paddingRight="#dimen/activityHorizontalMargin"
android:paddingTop="#dimen/activityVerticalMargin"
tools:context=".MainActivity">
<RelativeLayout
android:id="#id/mainHomeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true" />
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</TabHost>
There is another activity, in which tapping a button launches this activity. However, the activity doesn't launch and I get the following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nirvanapass/com.nirvanapass.MainActivity}: java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?
I have searched online - but whatever solutions I could find use ActivityGroup or TabActivity - both of which are deprecated. How to tackle this error and solve this problem?
The best solution is to use a modern tab solution. TabHost has been obsolete for quite some time. Using an Intent for a tab content has been deprecated for five years, and it was never a good idea even before then.
Most modern tab implementations use a ViewPager with some sort of tabbed indicator. PagerTabStrip and TabLayout are both in the Android SDK, and the Android Arsenal lists many other tab indicators in their ViewPager category.
If you really want the retro styling of a TabWidget, either use FragmentTabHost, or use TabHost where the tabs are views.
Here are sample apps for:
using PagerTabStrip
using TabLayout
using a third-party tab indicator
using TabHost with widgets for tabs
I am working on an Android project in which I have two different types of Chat possibilities. One is for Groups and other is for private or one to one communication. Now, all the Groups and Users the logged-in user can chat with is shown in ConversationActivity.
For this, I have prepared two lists in the UI, and contents will be added to each list by an Async method. Each List has a separate adapter, with which I will be able to easily identify, which item was clicked.
This mechanism is working just fine, except that when the activity is opened, the list look they are layered on top of each other, obviously that is not the intention. So I indicated in the RelativeLayout, to position it above another, that also didn't help.
How can I display two lists with two different adapters in one activity page?
activity_conversations.xml :
<?xml version="1.0" encoding="UTF-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip"
android:layout_above="#+id/privateRelativeLay"
>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/conversationList"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip"
android:id="#+id/privateRelativeLay">
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/privateConversationList"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
<ListView
android:id="#+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:dividerHeight="1dp" />
</android.support.v4.widget.DrawerLayout>
ConversationActivity.java
public class ConversationActivity extends ApplicationDrawerLoader {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_conversations);
if (isOnline()) {
new getConversationsForLoggedInUser(this).execute();
new getPrivateChannelsForLoggedInUser(this).execute();
}
public class getPrivateChannelsForLoggedInUser extends AsyncTask<Void,Void,ResponseEntity<PrivateChannel[]>>{
#Override
protected void onPostExecute(ResponseEntity<PrivateChannel[]> responseEntity) {
privateChannelConversationList = (ListView) findViewById(R.id.privateConversationList);
privateConversationAdapter = new PrivateConversationAdapter(conversationActivity, privateMapList);
privateChannelConversationList.setAdapter(privateConversationAdapter);
// On click adapter excluded
}
public class getConversationsForLoggedInUser extends AsyncTask<Void, Void, ResponseEntity<RestGroupAccount[]>> {
#Override
protected void onPostExecute(ResponseEntity<RestGroupAccount[]> responseEntity) {
super.onPostExecute(responseEntity);
groupAccountConversationList = (ListView) findViewById(R.id.conversationList);
groupConversationAdapter = new GroupConversationAdapter(conversationActivity, groupAccountMapList);
groupAccountConversationList.setAdapter(groupConversationAdapter);
// On click adpater excluded
}
}
I hope this much information is sufficient, if anything else is required, let me know. Any help would be nice. Thank you.
This is how it looks : screenshot :
They display on top of eachother because you put them both in a separate RelativeLayout that have the same positioning properties (none).
One fix would be to put both listViews in a LinearLayout instead. You can provide this LinearLayout with an orientation attribute vertical or horizontal, depending on how you want to display them, then use the layout_weight attribute to determine what portion of the screen each listviews occupies.
For example:
<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/listView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</ListView>
<ListView
android:id="#+id/listView2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</ListView>
</LinearLayout>
Note: fill_parent is legacy. Use match_parent instead.
It is because height of your both List Views is fill_parent. Try using wrap content or in your case i don't know how exactly do you want both List views to be displayed but I would suggest you use linear layout with orientation that you want and assign weights.
The layouts stack on each other in RelativeLayout as long as the cover the whole screen width and height.
Also fill_parent attribute value is deprecated now it is better to use match_parent.
I have been sitting for at least 4 hours trying to solve this problem.
To understand this there are 3 files you need to know about:
eggCatcher.java which extends Activity, this class is not used for much more than
saving gamestate and showing the optionsmenu.
eggCatcherView.java which extends SurfaceView and contains "the game".
eggCatcher_layout.xml which is shown below:
<?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:id="#+id/layouten">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<easter.fun.EggCatcherView
android:id="#+id/eggcatcher"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout android:id="#+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<TextView android:text="Score: "
android:id="#+id/totalscore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true">
</TextView>
<TextView android:text="Bonus: "
android:id="#+id/bonus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true">
</TextView>
</RelativeLayout>
</FrameLayout>
</LinearLayout>
As shown in the xml file, EggCatcherView is put in the xml file.
When the applications i started the onCreate calls setContentView(layout.eggcatcher_layout);
My question now is:
how can i, from EggCatcherView.java access and edit the TextViews defined in the xmlfile?
if it was in EggCatcher.java it would be easy, just use findViewById(id.bonus), but from
inside the surfaceView appears to be a little more difficult.
I hope i have made everything clear, if you dont understand just ask!
//micke
I think you should get the parent view and then from there on you can use findViewById() (are you sure you can't just use that method anyway since SurfaceView is a subclass of View and inherits findViewById() from it?).
For using the parent you do something like:
ViewParent vp = eggCatcherView.getParent();
FrameLayout fl = (FrameLayout) vp;
TextView tx = (TextView) fl.findViewById(R.id.bonus);
Of course you need to check if the ViewParent is indeed an instance of FrameLayout.
I found this the best way:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:id="#+id/test"/>
</LinearLayout>
TextView test = (TextView) findViewById(R.id.test);
test.setText("test");
If I understand correctly, you want to access the views in the surrounding activity? That seems like poor architecture. I think it would be better to either pass a callback to the EggCatcherView that can trigger methods in the Activity which in turn operate on the TextViews or fire some kind of events upwards.