I have an issue trying to fill a linear layout with cardviews inside, and inside of these, a view pager that is filled with two fragments. the fragments are filled with data stored in an SQLite database in a loop.
The issue is that only the last viewpager adapter calls the getItem function, making that all cards are empty except the last one.
This is the element layout
<?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="100dp"
android:orientation="vertical">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
card_view:cardCornerRadius="4dp">
<com.jaimedediego.cubemaster.view.CustomViews.CustomViewPager
android:id="#+id/detail_container"
android:layout_width="match_parent"
android:layout_height="100dp" />
</android.support.v7.widget.CardView>
</LinearLayout>
The CustomViewPager works exactly like a normal viewpager.
This is the function where a external linear layout is filled with elements with the previous layout. Where timesDetail is filled with the data
for (int i = 0; i < timesDetail.size(); i++) {
final Detail detail = timesDetail.get(i);
final View v = getLayoutInflater().inflate(R.layout.element_timesdetail_list, null);
final CustomViewPager viewPager = v.findViewById(R.id.detail_container);
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
#Override
public Fragment getItem(int position) {
return PlaceholderFragmentDetail.newInstance(position, detail);
}
#Override
public int getCount() {
return 2;
}
});
timesLayout.addView(v);
}
}
The getItem should be called for each loop to call the onCreateView of the PlaceholderFragmentDetail. but it doesn't (I think the issue is here). And it makes all cardview excepting the last one are empty.
The PlaceholderFragmentDetail call is
public static class PlaceholderFragmentDetail extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
private static final String DETAIL = "detail";
public PlaceholderFragmentDetail() {/*Do nothing*/}
public static PlaceholderFragmentDetail newInstance(int sectionNumber, Detail detail) {
PlaceholderFragmentDetail fragment = new PlaceholderFragmentDetail();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putSerializable(DETAIL, detail);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v;
Detail detail = (Detail) getArguments().getSerializable(DETAIL);
switch (getArguments().getInt(ARG_SECTION_NUMBER)) {
case 0:
v = inflater.inflate(R.layout.fragment_detail, container, false);
break;
case 1:
v = inflater.inflate(R.layout.layout_dialog_areyousure, container, false);
break;
default:
v = null;
break;
}
return v;
}
}
I really think that the issue is the getItem call of the FragmentPagerAdapter, but i don't know what i'm doing wrong.
Related
I've seen this questioned asked a number of times on here without an answer. I'm hoping if I ask it again maybe someone will be kind enough to help me with it.
I'm trying to implement a shared transition from an Item in a Recyclerview to a fragment.
I currently have my fragment transaction in the onBindView method of the adapter.
public void onClick(View v) {
...
activity.getSupportFragmentMnager().beginTransaction()
.addSharedElement(v, "SharedString")
.replace(R.id.container, fragment2)
.addToBackStack(null)
.commit();
}
In the android docs, addSharedElement(view and string) confuse me. How do I give the view a unique ID and should I even be using v here?
Can the string be what ever I want?
here is my implementation. There is FragmentList with RecyclerView with images on each item. And there is FragmentDetail with only on big image. Image from FragmentList list item fly to FragmentDetail. TransitionName of animated view on FragmentList and FragmentDetail must be same. So I give unique transition name for each list item ImageView:
imageView.setTransitionName("anyString" + position)
Then I pass that string to FragmentDetail via setArguments and set big image transitionName to that string. Also we should provide Transition which describes how view from one view hierarchy animates to another viewhierarchy. After that we should pass that transition to fragment. I do it before FragmentTransaction:
detailFragment.setSharedElementEnterTransition(getTransition());
detailFragment.setSharedElementReturnTransition(getTransition());
Or you can override getSharedElementEnterTransition and getSharedElementReturnTransition of Fragment and declare transition there. Here is full code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new FragmentList())
.commit();
}
}
public void showDetail(View view) {
String transitionName = view.getTransitionName();
FragmentDetail fragment = new FragmentDetail();
fragment.setArguments(FragmentDetail.getBundle(transitionName));
fragment.setSharedElementEnterTransition(getTransition());
fragment.setSharedElementReturnTransition(getTransition());
getSupportFragmentManager()
.beginTransaction()
.addSharedElement(view, transitionName)
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
private Transition getTransition() {
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
set.addTransition(new ChangeBounds());
set.addTransition(new ChangeImageTransform());
set.addTransition(new ChangeTransform());
return set;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
FragmentList:
public class FragmentList extends Fragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_list, container, false);
RecyclerView rv = view.findViewById(R.id.recyclerview);
rv.setAdapter(new ListAdapter());
return view;
}
private class ListAdapter extends RecyclerView.Adapter {
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Holder hold = (Holder) holder;
hold.itemView.setOnClickListener(v -> {
((MainActivity) getActivity()).showDetail(hold.imageView);
});
//unique string for each list item
hold.imageView.setTransitionName("anyString" + position);
}
#Override
public int getItemCount() {
return 10;
}
private class Holder extends ViewHolder {
ImageView imageView;
public Holder(View view) {
super(view);
imageView = view.findViewById(R.id.image);
}
}
}
}
fragment_list.xml
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
FragmentDetail:
public class FragmentDetail extends Fragment {
private static final String NAME_KEY = "key";
public static Bundle getBundle(String transitionName) {
Bundle args = new Bundle();
args.putString(NAME_KEY, transitionName);
return args;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_detail, container, false);
String transitionName = getArguments().getString(NAME_KEY);
ImageView imageView = view.findViewById(R.id.image);
imageView.setTransitionName(transitionName);
return view;
}
}
fragment_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/image"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="#drawable/cat"/>
</LinearLayout>
item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/cat"/>
</LinearLayout>
Here is result:
TransitionName may be any string you want.
There is ViewCompat.setTransitionName if you need support pre Lollipop devices.
Adding to the ashakirov's answer:
Problem
Return Transition was not working!
Reason:
On popbackstack from Fragment B to Fragment A, Fragment A's onCreateView is called and if your data is still loading then the return transition won't work with only ashakirov's code.
Solution
Postpone the transition in your fragments
Add this line where the loading starts in your fragment A:
postponeEnterTransition();
After your data is loaded or you've set your adapter, write this:
startPostponedEnterTransition();
This ensures that your transition only happens after your data is loaded.
Also, make sure you start the transition even in 'data failed to load scenarios'.
If you want to postpone the transition in your fragment B when going from A to B then add this to your fragment B:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//hold the transition
postponeEnterTransition();
//when the views are available then start the transition
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
and thank you for stopping by.
I've been facing a weird behavior using the combination of both PageTransformer and TransitionManager.
The hierarchy I'm using is fairly easy : A viewPager with each page being a fragment. The fragment has two different layouts, changing with the TransitionManager.go().
The issue :
If I just scroll through the viewPager, everything is fine, and my pageTransformer applies the right values, creating the desired parallax effect.
If I just click back and forth to change scenes inside a page, I also get the desired output.
However, whenever I use the TransitionManager.go() (let's say twice, to go back to the first layout) and then start scrolling through my viewPager, the parallax effect doesn't occur anymore.
My question :
Is there any known issue I haven't been able to find with using both a PageTransformer and a TransitionManager at the same time?
My code :
Fragment1.java
public class Fragment1 extends Fragment {
private Scene mStartScene;
private Scene mInfoScene;
private Transition mTransition;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.view_pager_item_default, container, false);
RelativeLayout rootLayout = (RelativeLayout) v.findViewById(R.id.p1);
mTransition = new ChangeBounds();
mTransition.setDuration(400);
mStartScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_default, getContext());
mInfoScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_details, getContext());
return (v);
}
public void changeScene(View v) {
Scene tmp = mInfoScene;
mInfoScene = mStartScene;
mStartScene = tmp;
TransitionManager.go(mStartScene, mTransition);
}
}
view_pager_item_default.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/p1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:elevation="20dp"
android:text="Item 1"
android:onClick="changeScene"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="60dp"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:padding="20dp"
android:layout_height="wrap_content"
android:background="#drawable/white_shape"
android:textSize="40sp"
android:gravity="center"
android:textColor="#000000"/>
<ImageView
android:id="#+id/imageView"
android:elevation="19dp"
android:scaleType="centerCrop"
android:layout_marginBottom="-10dp"
android:layout_centerHorizontal="true"
android:src="#mipmap/big_image"
android:background="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
view_pager_item_details.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/p1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:elevation="20dp"
android:text="Item 1 description"
android:onClick="changeScene"
android:layout_marginTop="150dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/white_shape"
android:clickable="true"
android:textSize="30sp"
android:gravity="center"
android:textColor="#000000"/>
<ImageView
android:id="#+id/imageView"
android:elevation="21dp"
android:layout_marginTop="50dp"
android:layout_centerHorizontal="true"
android:src="#mipmap/small_image"
android:background="#android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
My adapter is fairly simple :
public class MyPagerAdapter extends FragmentPagerAdapter {
private final List fragments;
public MyPagerAdapter(FragmentManager fm, List fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return (Fragment) this.fragments.get(position);
}
#Override
public int getCount() {
return this.fragments.size();
}
}
Then is my PageTransformer which moves each children of the view independently
public class MyPagerTransformer implements ViewPager.PageTransformer {
private float mParallaxCoeff;
private float mDistanceCoeff;
public MyPagerTransformer(float parallax, float distance) {
mParallaxCoeff = parallax;
mDistanceCoeff = distance;
}
#Override
public void transformPage(View page, float position) {
float coefficient = page.getWidth() * mParallaxCoeff;
ViewGroup vG = (ViewGroup) page;
for (int i = vG.getChildCount() - 1; i >= 0; --i) {
View v = vG.getChildAt(i);
if (v != null) {
v.setTranslationX(coefficient * (position * position * position));
}
coefficient *= mDistanceCoeff;
}
}
}
And lastly my Activity :
public class MainActivity extends AppCompatActivity {
private Fragment1 mFrag1;
private Fragment1 mFrag2;
private Fragment1 mFrag3;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
mViewPager = (ViewPager) findViewById(R.id.main_view_pager);
CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator);
if (mViewPager != null) {
mViewPager.setPageTransformer(true, new MyPagerTransformer(8.0f, 8.0f));
//vp.addOnPageChangeListener(listener);
List<Fragment> fragments = new ArrayList<>();
mFrag1 = new Fragment1();
mFrag2 = new Fragment1();
mFrag3 = new Fragment1();
fragments.add(mFrag1);
fragments.add(mFrag2);
fragments.add(mFrag3);
PagerAdapter realViewPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(), fragments);
mViewPager.setAdapter(realViewPagerAdapter);
indicator.setViewPager(mViewPager);
}
}
public void changeScene(View v) {
switch (mViewPager.getCurrentItem()) {
case 0:
mFrag1.changeScene(v);
break;
case 1:
mFrag2.changeScene(v);
break;
case 2:
mFrag3.changeScene(v);
break;
default:
break;
}
}
}
Lastly, here's a gif showing what happens. As you can see, at the beginning "Item 1" has the parallax effect. After switching scenes back and forth, the PageTransformer won't apply anymore.
Thanks in advance !
I will answer my own question in case anyone would bump into the same issue as I did.
The problem came from the rootLayout I was using in the fragment not being "the right one", therefore the TransitionManager was adding an extra layer when going back to the first scene.
Here's what I changed :
Fragment1.java
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//view_pager_root.xml is a simple empty FrameLayout
View v = inflater.inflate(R.layout.view_pager_root, container, false);
RelativeLayout rootLayout = (RelativeLayout) v.findViewById(R.id.p1);
mTransition = new ChangeBounds();
mTransition.setDuration(400);
mStartScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_default, getContext());
mInfoScene = Scene.getSceneForLayout(rootLayout, R.layout.view_pager_item_details, getContext());
return (v);
}
Since I added another layer into my hierarchy, I also had to change slightly my PageTransformer :
#Override
public void transformPage(View page, float position) {
float coefficient = page.getWidth() * mParallaxCoeff;
//vG is the FrameLayout
ViewGroup vG = (ViewGroup) page;
if (vG.getChildAt(0) instanceof ViewGroup) {
//vG is now the RelativeLayout from the scene
vG = (ViewGroup) vG.getChildAt(0);
for (int i = vG.getChildCount() - 1; i >= 0; --i) {
View v = vG.getChildAt(i);
if (v != null) {
v.setTranslationX(coefficient * (position * position * position));
}
coefficient *= mDistanceCoeff;
}
}
}
hello Friends i am little new to this Fragments concept!
Problem is
I am having a Actionbar with tabs and fragments now I want to implement viewpager inside one of the fragment of Actionbar tabs.
the point is to implement View pager with tabstrip inside a fragment
Please help me!
I hope that will be useful at least for anyone with the same problem if not for you.
You can put this fragment in every tab from action bar. The code is:
public class TabFragment extends Fragment {
ViewPager mViewPager;
DemoCollectionPagerAdapter mPagerAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab, container, false);
mPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager());
// Set up the ViewPager, attaching the adapter.
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
mViewPager.setAdapter(mPagerAdapter);
return view;
}
}
I took PagerAdapter from the Effective Navigation example and just removed the "static" attribute in order to move it in the separate file:
public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new DemoObjectFragment();
Bundle args = new Bundle();
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); // Our object is just an integer :-P
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// For this contrived example, we have a 100-object collection.
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
Bundle args = getArguments();
((TextView) rootView.findViewById(android.R.id.text1)).setText(
Integer.toString(args.getInt(ARG_OBJECT)));
return rootView;
}
}
}
And the fragment_tab.xml for this TabFragment is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip android:id="#+id/pager_tab_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>
Consider using a PagerTabStrip as a child view of ViewPager if you want the tab headers to be clickable and a PagerTitleStrip for them to be static (user can only swipe in order to switch to the tab).
Depending on your implementation of ActionBar with tabs I suppose there can arise some dependency problems because in this example I've used support library.
I have a ViewPager with 3 Fragments, each fragment has its own unique layout. Each Fragment knows which layout to use by getting layout id as parameter in newInstance() method from FragmentActivity that holds ViewPager. This ViewPager is controlled by FragmentStatePagerAdapter called MyPagerAdapter.
public class MainActivity extends FragmentActivity {
ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}
private class MyPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return FirstFragment.newInstance("FirstFragment, Instance 1");
case 1: return SecondFragment.newInstance("SecondFragment, Instance 1");
case 2: return ThirdFragment.newInstance("ThirdFragment, Instance 1");
}
}
#Override
public int getCount() {
return 3;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
public void setBackgroundImage(View view){
int i = pager.getCurrentItem();
Fragment page = ((MyPagerAdapter)pager.getAdapter()).getRegisteredFragment(i);
page.getView().findViewById(R.id.first).findViewById(R.id.button1);
page.getView().findViewById(R.id.first).setBackgroundResource(R.drawable.ic_launcher);
}
}
activity_main.xml:
<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=".MainActivity" >
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>
Here is the FirstFragment:
public class FirstFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_frag, container, false);
TextView tv = (TextView) v.findViewById(R.id.tvFragFirst);
tv.setText(getArguments().getString("msg"));
return v;
}
public static FirstFragment newInstance(String text) {
FirstFragment f = new FirstFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}}
first_frag.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_orange_dark"
android:id="#+id/first" >
<TextView
android:id="#+id/tvFragFirst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="26dp"
android:text="TextView" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/tvFragFirst"
android:text="Button"
android:onClick="setBackgroundImage"/>
</RelativeLayout>
It has more buttons and imagebuttons with onClick methods, but it's not necessary to the question, except that it's important to know that I have many onClick methods similar to setBackgroundImage that change appearance of layout.
the SecondFragment and ThirdFragment is similar, as their layouts.
As you can see the method setBackgroundImage in MainActivity, it changes background image of the fragment. But once its changed, it's not permanent, because as I flip through fragments and return to this first fragment the change isn't saved, but the original layout is shown. I understand that once out of vision, fragment's layout gets destroyed. Is there a way to retain layout changes?
Have you tried calling onRetainInstance(true) in the Fragments onCreate() method?
Certainly, one way to solve the problem would be to store in the Activity, the background resources for each fragment such that when the fragments are created, they are initialized correctly. This would also involve storing the background data in a bundle in the onSaveInstanceState() method.
I was able to create a tab layout using the tutorial in androidhive. I was wondering if I can put a side tab on it. . When you click an Item on the left side, an activity will be displayed on the right side.
I was wondering If I can do it. Thank you very much.
Try to design your layout as below:
Here its fragment_top_rated.xml file code:
<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=".MainActivity" >
<LinearLayout
android:id="#+id/passenger"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="2dp"
android:orientation="horizontal"
android:weightSum="1">
<FrameLayout
android:id="#+id/frameLayout1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight=".4"
android:background="#android:color/background_dark" >
</FrameLayout>
<FrameLayout
android:id="#+id/frameLayout2"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight=".6"
android:background="#android:color/darker_gray" >
</FrameLayout>
</LinearLayout>
</RelativeLayout>
You can load this screen on tabs click with the fragments into it.
EDITED:
Supposing that you have developed your project exactly same as the defined demo of you question link.
In your Tabactivity as you select places tab load the Fragment of places in the left side.
It defined in link on tab selected you just have to load fragments.
PlacesFragment
In your PlacesFragment write code as below:
public class PlacesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated,
container, false);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft1 = fm.beginTransaction();
Fragment m_fragSet = new GamesFragment();
ft1.replace(R.id.frameLayout2, m_fragSet);
ft1.commit();
FragmentManager fmg = getFragmentManager();
FragmentTransaction ftrans = fmg.beginTransaction();
Fragment m_frag = new MoviesFragment();
ftrans.replace(R.id.frameLayout1, m_frag);
ftrans.commit();
return rootView;
}
}
Create right side fragment Games
public class GamesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_games, container, false);
return rootView;
}
}
Here is MoviesFragment.java
public class MoviesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
return rootView;
}
}
In your TabsAdapter define as below:
public class TabsPagerAdapter extends FragmentPagerAdapter {
FragmentActivity context;
public TabsPagerAdapter(FragmentManager fm,FragmentActivity act) {
super(fm);
context=act;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
Here is the Output