How to clear ActionBar NavigationListMenu onPause() of fragment - android

Currenty, I have an activity with seven different child fragments in my android app. One of the fragment has to navigate a list menu but others do not have to navigate it or show it.
Frankly speaking, I don't want the other fragments use the NavigationListMode, however it will be activated also in all other fragments.
Is there anyway to perform this operation in Sherlock ActionBar Fragments?
I used the code snippet below to remove it for others, but I've never succeded (at anything what I have tried).
public class Fragment_Success extends SherlockListFragment implements ActionBar.OnNavigationListener
{
#Override
public void onPause()
{
super.onPause();
//academic_year_list.clear(); // Unsupported operation exception returned
getSherlockActivity().getSupportActionBar().getNavigationMode();
getSherlockActivity().closeOptionsMenu();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.layout_fragment_success, container, false);
...
String[] academic_year_array = getResources().getStringArray(R.array.academic_year);
Context context = getSherlockActivity().getSupportActionBar().getThemedContext();
ArrayAdapter<CharSequence> academic_year_list = ArrayAdapter.createFromResource(context, R.array.academic_year, R.layout.sherlock_spinner_item);
academic_year_list.setDropDownViewResource(com.actionbarsherlock.R.layout.sherlock_spinner_dropdown_item);
getSherlockActivity().getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getSherlockActivity().getSupportActionBar().setListNavigationCallbacks(academic_year_list, this);
...
return rootView;
}
...
}

Related

Different Activity each tab fragment

I have 3 tabs, and I'm trying to show a different activity and layout each tab.
I am using the tabs as my app navigation, so when a has changed, the whole layout and activity need to be changed.
Actually only the layout is changing.
Since the MainActivity.java + layout has the PageAdapter in it (the PageAdapter is loading the tab's content),
I have moved my first page activity from the MainActivity.java to a new java activity called showUpdates.java. Now I'm trying to access this activity as my Tab #1 content.
If you still didn't understand what I'm asking for, The following will make it clear:
My 3 tabs are:
Java: TabFragment1.java, XML: activity_show_updates.xml
Java: TabFragment2.java, XML: tab_fragment_2.xml
Java: TabFragment3.java, XML: tab_fragment_3.xml
The TabFragment1.java:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**
* Was trying:
* Intent intent = new Intent(...)
* startActivity(intent);
*/
return inflater.inflate(R.layout.activity_show_updates, container, false);
}
As you can see, it's moving to a new layout, activity_show_updates.xml.
What I'm trying to do is - using my showUpdates.java as the Activity of the tab_fragment_1.
I've been trying to use Intent but my app crashed when I created it at TabFragement1.java.
Anyone knows how I can make showUpdates.java as the activity of this layout?
You cannot nest activities. There are fragments for that. Just create a different fragment for each tab and use an Activity to hold all of them. If you need it, you can also create child fragments (although the support is not so good and you might have some problems, but nothing really hard to handle).
If you have viewpager working, you can do the following:
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
if(position == 0){
//return first fragment
}
else if(position == 1){
//return second fragment
}
...
}
and you can do your onCreate logic in onCreateView:
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View yourFragment = inflater.inflate (Resource.Layout.fragment_name, container, false);
... //do stuff
return yourFragment;
}
All you need to do is define which fragments to output in your adapter

Dynamically adding fragments from different sources

So I have MainActivity which is going to act as a container to hold two fragments; MainActivity is a subclass of FragmentActivity. The top fragment is a fragment with just a Spinner which is declared as an inner class in MainActivity:
public static class NavigationFragment extends Fragment {
public NavigationFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.navigation_fragment, container, false);
Spinner spinner = (Spinner)rootView.findViewById(R.id.menuSpinner);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.menuArray, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener((MainActivity)getActivity());
return rootView;
}
}
When MainActivity is loaded, I successfully get my top fragment:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.mainContainer, new NavigationFragment())
.commit();
}
}
The bottom fragment is the issue. In another file, I have FragmentA which doesn't really do much yet, but has some ui elements to see if its working; it's a subclass of Fragment. When the user changes the spinner's value, FragmentA will be removed and replaced with FragmentB. I'm trying to add the initial fragment it like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.mainContainer, new NavigationFragment())
.add(R.id.mainContainer, new FragmentA()) // THIS IS THE ONLY NEW LINE AND CAUSES THE ERROR
.commit();
}
}
I'm getting the error can't resolved method add(int, com.mybundle.myapp.FragmentA). I don't understand why, because adding NavigationFragment should be the same as adding FragmentA as they both extend Fragment
My question is, how do I properly dynamically add, then replace, fragments that are not inner classes of the main activity that holds them?
And my other question is, is this the proper way to achieve this kind of navigation flow? I've been working with iOS for several years, so the shift to Android is a little foreign to me as far as design and navigation patterns.
Check your definition files and make sure you use the same import for FragmentTransaction everywhere since FragmentTransaction API comes with the support version also to support android devices running 3.0 version and older

Is it the correct way? : To change a view/layout of Fragment on click

What I ought to do is change the view/layout of Fragment without creating another class for fragment on click of a button.
For example I have an activity - ContactsActivity and I have a fragment - ContactsFragment.
The Standard way of using Fragments:
From ContactsActivity I call ContactsFragment by -
getFragmentManager().beginTransaction().replace(android.R.id.content, new ContactsFragment())
.commit();
Code for setting View in ContactsFragment class -
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.contacts_primary, container, false);
return rootView;
}
**Now comes how I do what I want to do ** (Change the view of fragment)
I change only the view of ContactsFragment by doing a bad kind of hack.
I change the onCreateView() shown above to this -
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
//Set the view to R.layout.contacts_primary
rootView = inflater.inflate(R.layout.contacts_primary, container, false);
//Set the view to R.layout.contacts_secondary
if(getActivity().getIntent()!=null && getActivity().getIntent().getBooleanExtra("s", false)) {
rootView = inflater.inflate(R.layout.contacts_secondary, container, false);
Log.e(tag,getActivity().getIntent().getExtras().toString());
return rootView;
}
//This is the onClickListener which again calls the ContactsActivity class,
//this time with an Intent which I used above to change the view from
//R.layout.contacts_primary to R.layout.contacts_secondary
Button button = (Button)rootView.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getActivity(), ContactsActivity.class).putExtra("s",true));
}
});
Now everything works as I want and flawlessly.
But I have a very strong feeling that either all of it is wrong and Fragments aren't supposed to work this way or I am using a hectic hack to achieve what can be done by few lines of code.
So please let me know what is it? And if there is a standard way of doing what I am trying to do.
For me passing additional argument on which base fragment decides wich layout to use seems totally ok. But there is cleaner way of doing what you want to achieve without starting another activity.
First of all pass argument to fragment by making standard static new instance method in fragment (we cannot pass this argument in constructor as android always recreates fragments using empty constructor). Something like this:
public static ContactsFragment newInstance(boolan firstView) {
ContactsFragment fragment = new ContactsFragment();
Bundle args = new Bundle();
args.putBoolean("yourArg", firstView);
fragment.setArguments(args);
return fragment;
}
Every time you have to initiate your fragment do this with this method.
Then declare interface in your fragment to communicate with your activity. Like this
public interface NewViewListener {
public void showNewView(boolen firstView);
}
Than make your activity implement it so your activity han a method where it can place new fragment in container view. In your fragments onAttach and onDetach methodsmake sure your activity implements this interface and hold reference to your activity in private NewViewListener field in your fragment. Like this:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (NewViewListener ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement NewViewListener ");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
Then in on button click method call showNewView method on your activity with whatever argument you want indicating which view you want in new fragment instance. And in your activity method showNewVew fragment in the container. Like this:
#Override
public void showNewView(boolean firstView) {
getFragmentManager().beginTransaction().replace(android.R.id.content, ContactsFragment.newInstance(firstView)
.commit();
}
In your fragments onCreateView you may get passed arguments and decide which view you want to use.

Can a fragment extend a fragment activity? [Android]

I have created a MainActivity which consists of 3 tabs which are scrollable (by using ViewPager). Now each of these 3 tabs is a Fragment. Also, I am using ActionBarSherlock (ABS).
For the 1st Fragment, I have created the following class:
public class Fragment_1 extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment1, container, false);
return v;
/* R.layout.fragment1 only contains a TextView. */
}
}
For the 2nd Fragment, I want to extend a FragmentActivity as shown below.
public class Fragment_2 extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment2);
}
}
The 3rd Fragment is same as the first one.
But when I launch the app, it crashes. So, am I wrong in extending FragmentActivity for the class Fragment_2? Is it illegal to extend a FragmentActivity or even an Activity to fragment classes? If not, what is the problem here?
Thanks.
EDIT: After #CommonsWare's answer I updated my class as follows:
public class Fragment_2 extends SherlockFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button send = (Button) findViewById(R.id.bSend); //Error at this line
//some error free code
FragmentTransaction t = getSupportFragmentManager().beginTransaction(); //Error at this line
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment2, container, false);
return v;
}
My final two questions are:
How should I access my R.id.bSend Button in the Fragment_2 class.
Eclipse is giving the suggestion to change getSupportFragmentManager() to getFragmentManager(). Is that change all right?
Thanks!
Is it illegal to extend a FragmentActivity or even an Activity to fragment classes?
Fragment is a Java class. Your fragment implementations (for use as pages in your ViewPager) must inherit from Fragment, directly or indirectly.
Activity does not inherit from Fragment. FragmentActivity does not inherit from Fragment. Hence, you cannot inherit from Activity or FragmentActivity and somehow also inherit from Fragment.

Keeping tab fragment view unchanged

I have a tabbed application using fragments. Following is a code snippet from one of the fragments in tabA
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
accountsView = inflater.inflate(R.layout.activity_accounts, viewGroup, false);
//obtain the labels- Top 50 Spending aacounts
spendingLabel = (TextView) accountsView.findViewById(R.id.textView1);
//get search box
accountSearch = (EditText) accountsView.findViewById(R.id.vAccountSearch);
return accountsView;
}
Here is the onStart()
#Override
public void onStart() {
super.onStart();
fillData();
}
fillData() fetches dat from the server. The application now fills a listView on tab click (by calling fillData() ). If I switch to other tabs and come to tabA, the page again calls fillData() and recreates the whole view.
How do I stop it reloading and keep the view unchanged on tab switching?
Since I am a newbie into Fragments, I find it hard to find a solution. Has anyone dealt this before?
According to the lifecycle of Android application try to override onCreate instead of onStart
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fillData();
}

Categories

Resources