ActionbarSherlock Fragment in Fragment - android

I don't know it's a problem of my application structure or a problem with my code.
I have a tabActivity which extends SherlockFragmentActivity.
This has a ViewPager and a TabsAdapter.
There are two Tabs and one OptionsMenu item ("search").
The two tabs are for entering search parameters. One simple, one detaild. If search is clicked, a search is performed and the results shall be shown.
The content of the tabs are already objects of the type SherlockFragment. So far, this works fine.
At the moment, the search results are a seperate activity. I would like to have them in the viewpager as well. So I converted it to a SherlockActivity. But if I make ("this" is the tabActivity) in the onCreate() Method:
FragmentManager fm = this.getSupportFragmentManager();
Fragment ft = Fragment.instantiate(this, searchFragment.class.getName(), null);
if(fm.findFragmentById(R.id.searchresults_content) == null)
{
fm.beginTransaction().add(R.id.searchresults_content, ft).commit();
}
and then:
this.mViewPager.addView(ft.getView());
but ft.getView(); returns null. OnCreateView from searchFragment will do this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
WebView mWebView = (WebView)findViewById(R.id.search_results);
View mView = inflater.inflate(R.layout.search_results, container, false);
mWebView.setWebViewClient(new SearchResultsWebViewClient());
//... (load data for webview etc...)
return mView;
}
search_results.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id ="#+id/search_results"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</WebView>
</LinearLayout>

Related

Android views in fragments overlapping

So I've read several tutorials and many of the posts on SO but I still can't get this to work. I'm trying to use dynamically added fragments but when loading a fragment TextViews and ImageViews in the fragment keep overlapping instead of updating their values, like so:
and fragments overlap each other when replaced.
I got a main activity (extending AppCompatActivity) split into 2 layouts:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_white"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/upperFrameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/lowerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
...
The upper FrameLayout contains my fragments. The fragments are replaced in this method in the MainActivity-class:
void setMode() {
// Show "find opponent"- or "fight"-fragment
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
if (!debugFight && (btCoordinator == null || !btCoordinator.isConnected())) {
fragmentTransaction.replace(R.id.upperFrameLayout, new FindOpponentFragment());
} else {
fragmentTransaction.replace(R.id.upperFrameLayout, new FightFragment());
}
fragmentTransaction.commitNow();
}
What am I missing?
EDIT: Added FightFragment onCreateView()-method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
((TextView) inflater.inflate(R.layout.fragment_fight, container, false).findViewById(R.id.score_textView)).setText(getString(R.string.score, 0, 0));
((TextView) inflater.inflate(R.layout.fragment_fight, container, false).findViewById(R.id.opponent_textView)).setText(MainActivity.opponentName.toUpperCase());
final AnimatedVectorDrawableCompat animated = AnimatedVectorDrawableCompat.create(container.getContext(), R.drawable.loading_animated_vector);
animated.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
#Override
public void onAnimationEnd(Drawable drawable) {
animated.start();
}
});
((ImageView) inflater.inflate(R.layout.fragment_fight, container, false).findViewById(R.id.opponent_hand_imageview)).setImageDrawable(animated);
animated.start();
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fight, container, false);
}
...and as I pasted this piece of code I just realised that those inflated views are all different objects. I replaced them with a single object which I modify and then let the method return and it works. I guess I have to read up on views and the inflate-method.
use fragmentTransaction. add() instead of replace()
Use this above the fragment commit
fragmentTransaction.addToBackStack(null);
I didn't understand how the inflate-method. I modified my fragments onCreateView-method as seen in the OP and now it works.

xamarin navigate from one fragment to another

I am trying to navigate from on fragment to another by click a button in original fragment. How ever I got a Exception
Image of exception
Image of my code for the original Fragment
The problem is that you are passing a Layout in your call of transaction.Replace(), instead you should pass the Id the of the ViewGroup where the fragment will be inserted in your layout.
so the layout of the activity containing your fragments should look something like this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="fill_parent" />
</FrameLayout>
And in your FragmentStockSearch fragment, override OnCreateView to something like this:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(Resource.Layout.your_layout, null, false);
}
and finally your fragment transaction code:
var trans = new FragmentManager.BeginTransaction();
trans.Replace(Resource.Id.content_frame, new FragmentStockSearch(), "FragmentStockSearch");
trans.AddToBackStack(null);
trans.Commit();

ViewPager fragments created but not beeing displayed on Android <= Jellybean

I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/main_container_1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/main_container_2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<FrameLayout
android:id="#+id/leftDrawer"
android:layout_width="#dimen/some_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingTop="?android:attr/actionBarSize" />
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
I have inserted a fragment in main_container_1 which has a layout with a viewPager created programmatically. Here is the OnCreateView of the first fragment
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var frameLayout = new FrameLayout(Activity)
{
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent)
};
_viewPager = new ViewPager(Activity);
//It is required that view pager have an ID othe than -1
_viewPager.Id = 0x00000001;
_viewPager.PageSelected += _viewPager_PageSelected;
_progressBar = new ProgressBar(Activity)
{
LayoutParameters = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent, GravityFlags.Center)
};
frameLayout.AddView(_viewPager);
frameLayout.AddView(_progressBar);
return frameLayout;
}
Of course, later on, I bind my data via an FragmentStatePagerAdapter to the viewPager.
Result: The child fragments contained in the first fragment display properly
I do the same operation for a second fragment in main_container_2 of a different type which has the following onCreateView
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
_myCustomContainer = (MyCustomLayout)inflater.Inflate(Resource.Layout.MyCustomLayout, container, false);
_viewPager = new ViewPager(Activity);
_myCustomContainer.AddView(_viewPager);
//It is required that view pager have an ID othe than -1
_viewPager.Id = 0x00000001;
return _myCustomContainer;
}
I use the same type of FragmentStatePagerAdapter as for the first viewPager of the first fragment.
Result: On Android version lower or equal to Jellybean (API 16), the child fragments of the second fragment are created but not displayed.
Here is the GetItem method of my implementation of the FragmentStatePagerAdapter
public override Fragment GetItem(int position)
{
if (!ActiveFragments.ContainsKey(position))
{
var fragment = PagedCustomFragment.NewPagedCustomFragment(position);
ActiveFragments[position] = fragment;
}
return ActiveFragments[position];
}
Question: Why are the child fragments of the second fragments not shown?
Both your ViewPagers seem to belong to the same parent and also have the same ID, which might be the root cause of your issue. Have you tried to use a different ID for each ViewPager?

Nested Fragments. How to know when all of them are attached to the activity?

My application uses multiple nested fragments. Some of these fragments are placeholders. When I try to replace placeholders with initial set of fragments I get
java.lang.IllegalStateException: Activity has been destroyed
I am sure that activity is fine and the issue is caused by fragments not being attached to the activity. So how do know when all nested fragments are attached to the activity?
Additional information about my setup:
I have an Activity that has fragment declaration in it's layout file:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/rightPane"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.company.PagerFragment"/>
</LinearLayout>
The PagerFragment is the host for view pager.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
I put two Fragments into the pager. They serve as placeholders.
I want to replace placeholders with initial fragments but when I initiate the replacement in activity's onCreate method I get the aforementioned exception.
Everything works fine if I use new Handler().postDelayed(..) in activity's onCreate method. I would rather to not use the delay approach for obvious reasons.
I tried to replace placeholders in other activity's methods like onStart(), onResume(), onResumeFragments(), onPostResume() but that didn't help.
EDIT:
public class PagerFragment extends Fragment
{
..
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_right_pane, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState == null)
{
m_primary = new PlaceholderFragment();
m_secondary = new PlaceholderFragment();
}
else
{
FragmentManager fm = getChildFragmentManager();
m_primary = (PlaceholderFragment)fm.getFragment(savedInstanceState, FRAGMENT_TAG_PRIMARY);
m_secondary = (PlaceholderFragment)fm.getFragment(savedInstanceState, FRAGMENT_TAG_SECONDARY);
}
Fragment[] fragments = new Fragment[] { m_primary, m_secondary };
PagerAdapter pagerAdapter = new FragmentPagerAdapter(getChildFragmentManager(), fragments);
m_viewPager = (ViewPager)view.findViewById(R.id.pager);
m_viewPager.setAdapter(pagerAdapter);
m_viewPager.setOnPageChangeListener(this);
m_viewPager.setCurrentItem(0, true);
}
..
}

Fragments inside a fragment Android application

I'm trying to put 2 fragments inside a fragment. I found some code on internet but, as far as I could go, I don't succeed to put 2 fragments in 1 fragment.
I have seen tips dealing with FragmentManager and especially the method getChildFragmentManager() but I don't know how it works with 2 fragments.
For the story, I'm using an activity with ActionBar which creates 3 fragments. In one of them, I need to handle a graph and a kind of menu to change the graph scale. In this way, I need 2 fragments in one fragment.
Here is the code :
The fragment which handles the others:
public class GraphDisplayFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.graph_fragment, container, false);
return myFragmentView;
}
}
The code to draw the graph:
public class GraphFragment extends Fragment {
private static final int SERIES_NR = 1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
GraphicalView myFragmentView = ChartFactory.getTimeChartView(this.getActivity(), getDateDemoDataset(), getDemoRenderer(),null);
return myFragmentView;
}
//some functions to set graph propreties
}
The XML files :
graph_fragment.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" >
<fragment
android:id="#+id/graph_fragment"
android:name="com.test.GraphFragment"
android:layout_width="match_parent"
android:layout_height="259dp" >
</fragment>
<fragment
android:name="com.test.GraphDetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/graph_detail_fragment">
</fragment>
</LinearLayout>
graph_detail.xml with a test implementation
<?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="211dp"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
The weird thing is, it works at the begining when I switch between fragments in the ActionBar but after 3-4 moves, I get this error :
android.view.InflateException: Binary XML file line #7: Error inflating class fragment
If anyone has the solution, it would be awesome!
So first off change your xml for graph_fragment.xml to this
<?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/graph_fragment_holder"
android:layout_width="match_parent"
android:layout_height="259dp" >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/graph_detail_fragment_holder">
</FrameLayout>
</LinearLayout>
Then in code to inflate them from the fragment use something like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.graph_fragment,
container, false);
FirstChildFragment frag1 = (FirstChildFragment) getChildFragmentManager()
.findFragmentById(R.id.first_frag_layout);
SecondChildFragment frag1 = (SecondChildFragment) getChildFragmentManager()
.findFragmentById(R.id.second_frag_layout);
if (null == frag1) {
FirstChildFragment = new frag1();
FragmentTransaction transaction = getChildFragmentManager()
.beginTransaction();
transaction.add(R.id.graph_fragment_holder, frag1)
.addToBackStack(null).commit();
}
if (null == frag2) {
SecondChildFragment = new frag2();
FragmentTransaction transaction = getChildFragmentManager()
.beginTransaction();
transaction.add(R.id.graph_detail_fragment_holder, frag2)
.addToBackStack(null).commit();
}
return rootView;
}
MyFragment myFragment = (MyFragment)getChildFragmentManager().findFragmentById(R.id.my_fragment);
You can try to use the method *findFragmentById(fragment_id)* from SupportFragmentManager to get the instance of fragment from your .xml file and insert your fragment there.
Something like:
Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.myFragmentId);
I hope to help you.
Best regards.
Adriano

Categories

Resources