I have a Fragment class, called from by FragmentTabHost, which does not display nothing.
This is my ArticulosFragment class:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ArticulosFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("App", "asdasdasd");
return inflater.inflate(R.layout.fragment_articulos, container, false);
}
}
I have a simple TextView in the XML 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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Articulos"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
When I run the app, the log added shows correctly, but the text Articulos doesn't.
Edit: This is my TabHost class which displays (or should displays) the ArticulosFragment class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(),
android.R.id.tabcontent);
inicializarTabs();
}
public void inicializarTabs() {
TabHost.TabSpec spec = tabHost.newTabSpec("Articulos");
spec.setContent(new TabContentFactory() {
#Override
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator("Articulos");
tabHost.addTab(spec, ArticulosFragment.class, null);
}
Two Things That Might Cause That:
Check If The Container coming is null for view
Check you Code For Fragment that show Fragment
Try Removing onCreate method from Fragment
TabContentFactory
Makes the content of a tab when it is selected. Use this if your tab
content needs to be created on demand, i.e. you are not showing an
existing view or starting an activity.
Please notice this line:
you are not showing an existing view or starting an activity.
public abstract View createTabContent (String tag)
Callback to make the tab contents
Parameters
tag Which tab was selected.
Returns
The view to display the contents of the selected tab.
So because you have a fragment and it is already have a view you do not need createTabContent and the interesting part is:
https://github.com/android/platform_frameworks_support/blob/master/v13/java/android/support/v13/app/FragmentTabHost.java#L219
as you see fragmentTabHost overwrites your TabContentFactory.
anyway your problem is:
tabHost.setup(this, getSupportFragmentManager(),android.R.id.tabcontent);
change it to:
tabHost.setup(this, getSupportFragmentManager(),R.id.realtabcontent);
Related
I have one activity and two tabs in that activity Tab1 and Tab2. These are the two fragments. In my Tab1 have an EditText field and a Button field and Tab2 have only one TextView Field.I want to get the value in EditText field in the Tab1 in to TextView field in Tab2 when I click the button in the Tab1 and also get value when swipe Tab1 to Tab2. I also check many websites but did't get any solution. If anyone know it please help me.
MainActivity.java
package reubro.com.fragment;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
TabLayout tabLayout;
ViewPager viewPager;
Tab1 t2;
EditText ed1;
Tab1 t1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t1 = new Tab1();
ed1 = (EditText) findViewById(R.id.ed1);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tab);
viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab2"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
Pager pager = new Pager(getSupportFragmentManager(),tabLayout.getTabCount());
viewPager.setAdapter(pager);
tabLayout.setOnTabSelectedListener(this);
}
public void onTabSelected(TabLayout.Tab tab){
viewPager.setCurrentItem(tab.getPosition());
// ed1.setText(t1.ed.getText());
// Log.d("cccccc",ed1.getText().toString());
}
public void onTabUnselected(TabLayout.Tab tab) {
}
public void onTabReselected(TabLayout.Tab tab) {
}
}
Tab1.java
package reubro.com.fragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
/**
* Created by pc84 on 20/1/17.
*/
public class Tab1 extends Fragment {
Button b1;
EditText ed;
String val;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, final Bundle bundle){
View view = inflater.inflate(R.layout.tab1,viewGroup,false);
b1 = (Button) view.findViewById(R.id.btn1);
ed = (EditText) view.findViewById(R.id.ed1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
val = ed.getText().toString().trim();
if(!(val.isEmpty())){
Log.d("inner",val);
Tab2 tab2 = new Tab2();
Bundle bundle = new Bundle();
bundle.putString("val",val);
tab2.setArguments(bundle);
Toast.makeText(getActivity(),"This is value: "+val,Toast.LENGTH_LONG).show();
}
}
});
return view;
}
}
Tab2.java
package reubro.com.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by pc84 on 20/1/17.
*/
public class Tab2 extends Fragment {
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle){
View view = inflater.inflate(R.layout.tab2,viewGroup,false);
tv = (TextView) view.findViewById(R.id.tv1);
Bundle bundle1 = this.getArguments();
if (bundle1 != null){
String val = bundle1.getString("val");
tv.setText(val);
Log.d("tttttt",val);
}
return view;
}
}
Pager.java
package reubro.com.fragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
/**
* Created by pc84 on 20/1/17.
*/
public class Pager extends FragmentStatePagerAdapter {
int tabCount;
public Pager(FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
Tab1 tab1 = new Tab1();
return tab1;
case 1:
Tab2 tab2 = new Tab2();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return tabCount;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/tab"
/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/ed1"
android:hint="Enter something"
android:layout_margin="20dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:id="#+id/btn1"
android:layout_below="#+id/ed1"
android:text="Send to Next Fragment"
android:textAllCaps="false"/>
</RelativeLayout>
tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Tab2"
android:gravity="center"/>
</RelativeLayout>
You can place your data into a Singleton referenced both into Tab1 and Tab2.
A Singleton is a programming pattern that let you to use always the same and the only one instance of a class.
This is an example:
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
Take a look here to have a more detailed description:
Use ViewModel as a parent data sharing in the parent activity so you can use the same context as viewLifeCycleOwner so you can easily handle the data view and data
To pass data from one tab to another, you can either send a broadcast or if you don't want to broadcast then first pass it to activity through callback then from activity to tab2.
You try to use BroadcastReceiver.
In Tab1 : you send broadcast with data
In Tab2 : you get data from broadcast and set page index
You Can use Live Data object with View Model You can Implement it easily with new Android Architecture.
Doc : https://developer.android.com/topic/libraries/architecture/livedata
No need to EventBus Anymore and Interface for getting LiveData.
I've encountered a similar scenario and came up with the following:
Have the MainActivityViewModel hold any data you may need, and set
it accordingly when the event you are interested in is triggered.
You can then trigger the navigation to the destination tab
programmatically(even if you are using the multiple-stack workaround
used here
https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample),
and have it get any information it may need from the
MainActivityViewModel.
As soon as the information is read, set it to null so it won't be
used again by mistake. You should also have a default behavior, for
when the tab comes up for other reasons, and that variable is null.
Honestly, I'm not sure if by doing this I've gone against some best practices or something, but it has proven useful, and doesn't feel too "hacky".
if your willing to wait until the tab is resumed:
it can be done like this: in your main activity navigation host have a function like this:
fun moveToTabPosition(tabPosition: Int, bundle: Bundle?) {
myFragment?.arguments?.let { it.putAll(bundle) } ?: run { myfragment?.arguments = bundle }
binding.tablayout.setSelectedTab(tabPosition)
binding.yourViewPager.currentItem = tabPosition
}
then just call that with your new bundle updates.
important: in onResume of each tab fragment have a function called updateBundle() and parse the arguments you want again.
the key here is the the arguments have a method called putAll
UPDATE: I want to avoid putAll now ...i notice after Android N it cannot allow to add values to the arguments after the fragment is attached. During QA testing it passed but some users had this issue so had to remove this call.
i got an error on some devices of: java.lang.UnsupportedOperationException : ArrayMap is immutable
Now im in favor of a common interface to call to update the set the arguments data. it would take a bundle as param.
I’m trying to initialize ViewPager in Fragment (ViewPager pager = fragmentNews.getPager()), but it’s still null:
My fragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class NewsFragment extends Fragment {
private ViewPager pager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_news, container, false);
pager = (ViewPager) view.findViewById(R.id.sliding_pager);
return view;
}
public ViewPager setAdapterForPager(PagerAdapter adapter){
pager.setAdapter(adapter);
return pager;
}
public ViewPager getPager() {
return pager;
}
}
Here is my MainActivity:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.container_for_fragments, fragmentNews).commit();
pagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
ViewPager pager = fragmentNews.getPager();
pager.setAdapter(pagerAdapter);
...
fragment_news.xml:
<LinearLayout 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"
android:orientation="vertical"
android:weightSum="100"
tools:context=".fragments.NewsFragment">
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sliding_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="30" />
...
</LinearLayout>
But in NewsFragment.java pager remains null. So after launching I have got RuntimeException, mistake in row:
pager.setAdapter(pagerAdapter); in MainActivity.java
Without trying to initialize the ViewPager, the app works fine.
Here
pager.setAdapter(pagerAdapter);
line causing issue because pager is null.
Why?
Because using two different objects of NewsFragment : one for calling getPager method another which is passing in add method as last parameter.
Use same object which is passed in add method of accessing View's,methods,... from NewsFragment Fragment.
Most likely, the onCreateView of the fragment hasn't been executed yet. It takes time adding a Fragment to your Activity. You can't assume it happened right after adding it.
What you can do is overwrite onViewCreated in the Fragment that notifies the Activity in some way that it is created.
Also, where is fragmentNews coming from? you do a new NewsFragment() in the transaction but it's not saved to fragmentNews so you have two seperate Fragments it seems.
EDIT:
You could do it like this I think
Add this your Fragment:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MainActivity) getActivity()).viewIsCreated();
}
And this in your activity
public void viewIsCreated() {
ViewPager pager = fragmentNews.getPager();
pager.setAdapter(pagerAdapter);
}
And remove those two lines from the onCreate
EDIT : after some experimentation, it looks like it works as expected if I don't add the initial fragment in the xml layout. I am now doing it in my activity source code. I suppose this is how I was expected to do it ?
According to http://developer.android.com/guide/components/fragments.html#Creating , if a fragment is removed and then added back, onCreateView() should be called.
I also can see that getView() returns null.
onDestroyView() is called but the interface of my first fragment is still displayed when back is pressed
here is the result of my sample code :
--launch app
I/System.out( 3765): ==== FRAGMENT1.ONCREATE
I/System.out( 3765): ==== FRAGMENT1.ONCREATEVIEW
I/System.out( 3765): ==== FRAGMENT1.ONACTIVITYCREATED (FRAGMENT1.getView = android.support.v4.app.NoSaveStateFrameLayout#41301268
--second fragment
I/System.out( 3765): ==== FRAGMENT2.ONCREATE
I/System.out( 3765): ==== FRAGMENT2.ONCREATEVIEW
I/System.out( 3765): ==== FRAGMENT2.ONACTIVITYCREATED
--back is pressed : getView() == null and onCreateView is not called
I/System.out( 3765): ==== FRAGMENT1.ONACTIVITYCREATED (FRAGMENT1.getView = null
In case I am doing something wrong, here is some basic code to reproduce my issue :
my 2 fragment classes :
package com.test.testbackfragment;
import android.support.v4.app.Fragment;
import android.view.ViewGroup;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
public class Fragment1 extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
System.out.println("==== FRAGMENT1.ONCREATE");
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("==== FRAGMENT1.ONCREATEVIEW");
View v = inflater.inflate(R.layout.fragment1, container, false);
v.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction()
.remove(Fragment1.this)
.add(R.id.fragment, new Fragment2())
.addToBackStack(null)
.commit();
}
});
return v;
}
#Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
System.out.println("==== FRAGMENT1.ONACTIVITYCREATED (FRAGMENT1.getView = "+getView());
}
}
and
package com.test.testbackfragment;
import android.support.v4.app.Fragment;
import android.view.ViewGroup;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
public class Fragment2 extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
System.out.println("==== FRAGMENT2.ONCREATE");
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("==== FRAGMENT2.ONCREATEVIEW");
View v = inflater.inflate(R.layout.fragment2, container, false);
return v;
}
#Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
System.out.println("==== FRAGMENT2.ONACTIVITYCREATED");
}
}
main activity is very simple
package com.test.testbackfragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
and here are the 3 layouts :
main.xml
<?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" >
<fragment android:name="com.test.testbackfragment.Fragment1"
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
fragment1.xml
<?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"
android:background="#0000FF">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dip"
android:text="THIS IS FRAGMENT1" />
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dip"
android:text="FRAGMENT2"/>
</LinearLayout>
fragment2.xml
<?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"
android:background="#00FF00">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dip"
android:text="THIS IS FRAGMENT2" />
</LinearLayout>
When the system creates this main.xml layout, it instantiates fragment specified in the layout and calls the onCreateView() method, to retrieve each fragment's layout. later on it will use same fragment instantiates. So, it won't call OnCreateView again.
If you want to create again, get an instance of FragmentTransaction from your Activity and implement as you like.
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction .replace(R.id.fragment, newFragment);
// Commit the transaction
transaction.commit();
Try to remove the fragment from the stack of FragmentManager by using
FragmentTransaction.remove(your fragment) before BackPress event.
or Just use the FragmentTransaction.replace() to load the new fragment.
I have 4 views, two of which contain mapviews. What I really want in the end is a tabbed navigation between these 4 views.
After some research, it seams like the best idea would be to use ActionBarSherlock and make each one of these views a "Fragment" inside a master "Main" Activity. This seams like a very easy to do thing but is causing me massive amounts of trouble (indeed, seams to be a pain for everyone from what I can find online).
First, my code.
ActivityMain.java
public class ActivityMain extends SherlockFragmentActivity
{
static String CLASS_NAME = "ActivityMain";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
Log.v(CLASS_NAME, "here");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.createMenu();
}
public void createMenu()
{
this.getSupportActionBar().setDisplayShowHomeEnabled(false);
this.getSupportActionBar().setDisplayShowTitleEnabled(false);
this.getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab1 = getSupportActionBar()
.newTab()
.setText("First tab")
.setTabListener(new MyTabListener<FragmentOne>(this, FragmentOne.class));
getSupportActionBar().addTab(tab1);
Tab tab2 = getSupportActionBar()
.newTab()
.setText("Second tab")
.setTabListener(new MyTabListener<FragmentTwo>(this, FragmentTwo.class));
getSupportActionBar().addTab(tab2);
}
public class MyTabListener<T extends Fragment> implements TabListener
{
private ActivityMain mActivity;
private Fragment mFragment;
private Class<T> mClass;
public MyTabListener(ActivityMain activity, Class<T> fragmentClass)
{
mActivity = activity;
mClass = fragmentClass;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
if (mFragment == null)
{
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, null);
}
else
{
//ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.animationtest);
ft.attach(mFragment);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
{
if (mFragment != null)
{
ft.detach(mFragment);
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
{
}
}
}
FragmentOne loads just fine, no problems on that one. FragmentTwo is where the trouble begins. Here is the files:
FragmentTwo.java
package com.test;
import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentTwo extends SherlockFragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.v("Test", "Two!");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.two, container, false);
return view;
}
}
and the corresponding layout looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapMapView"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="0.40"
android:clickable="true"
android:apiKey="MY_KEY"
/>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="#android:style/ButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/refreshButton"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:onClick="refreshSightings"
android:text="#string/A_MAP_REFRESH_BUTTON" />
</LinearLayout>
</LinearLayout>
Now of course this is giving me the error Binary XML file line #7: Error inflating class com.google.android.maps.MapView
I have tried importing the https://github.com/petedoyle/android-support-v4-googlemaps package and replacing the already existing android-support-v4 package but when I try to run my app, it dies with the error that it can't find the ActivityMain class.
First question, am I even going about this in the right way? Should I be using this 1 main activity and loading all the other things in Fragments?
Next, if I am doing this in a correct way, is there a good tutorial for how to get this to work in a decent way? I can't find anything online except for other people asking the same questions and a few tutorials that haven't worked for me.
Basically, how can I have tabbed navigation with 2 maps in 2 different tabs?
I am trying to make a very simple App, but there's an error I can't get rid of it. Maybe someone can help me.
I'm making an Activity with an ActionBar and 3 Tabs. Beneath the Tabs is a FrameLayout, where I put Fragments with a TextView in it. So when clicking on a tab the content of the TextView shoud change.
This works fine until I change the orientation. After the change there is a duplicate TextView and I have no idea where it cames from. Here's a picture for better understanding:
Overlapping TextViews
Here's my Activity:
package com.test;
import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.app.ActionBar.Tab;
import android.os.Bundle;
import android.widget.Toast;
public class ProblemActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
String tab1 = "First Tab";
bar.addTab(bar
.newTab()
.setText(tab1)
.setTabListener(
new TabListener(new First())));
String tab2 = "Second Tab";
bar.addTab(bar
.newTab()
.setText(tab2)
.setTabListener(
new TabListener(new Second())));
String tab3 = "Third Tab";
bar.addTab(bar
.newTab()
.setText(tab3)
.setTabListener(
new TabListener(new Third())));
}
private class TabListener implements ActionBar.TabListener {
private MyFragment mFragment;
public TabListener(MyFragment fragment) {
this.mFragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_content, mFragment, null);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(ProblemActivity.this, "Reselected!", Toast.LENGTH_SHORT)
.show();
}
}
}
The Fragment's:
public class First extends MyFragment {
public First() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragView = inflater.inflate(R.layout.tab1, container, false);
TextView tv = (TextView) fragView.findViewById(R.id.textView1);
tv.setText("First Tab");
return fragView;
}
}
main.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:orientation="vertical" >
<FrameLayout
android:id="#+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
and the content of the Fragment's.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:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="TextView"
android:textSize="35dp" />
</LinearLayout>
It would be amazing if some could show me what I'm making wrong.
Thank's in advance!
Edit: I tried already this proposed solution but I would like to work with class Objects, so that I can use their Methods.
Edit2: Solved the problem now. It was sufficient to add android:configChanges="keyboardHidden|orientation|screenSize" to my Activity.
Since the OP already solved his problem, but hasn't been active on SO for almost a year, here is an answer containing the solution:
Adding the following to the Activity solved the problem:
android:configChanges="keyboardHidden|orientation|screenSize"
You can get overlapping views if there is something wrong with one of your layouts. This seems to happen in particular if you have a fragment. For example, a View in the Fragment can overlap a View in the containing layout.
Sometimes this can be fixed by Cleaning your project (if you are using Eclipse).