Honeycomb: Several fragments in each Tab in Action Bar - android

I'm quite new to android and java and I want to implement the following functions in action Bar:
TAB 1 : Displays ListFragment A and Listfragment B
TAB 2 : Displays ListFragment C and Listfragment D
I already made the code to display a view with ListFragment A and Listfragment B but without action Bar. I'm trying to integrate action bar with tabs and now it is not working and I'm not able to figure out what is wrong or find a post with a solution.
I'm using an activity for each Fragment.
At the moment, I can display one fragment in each tab with the action bar :
fragment A appears when I click in Tab 1
Fragment C appears when I click in Tab 2
My Problem is:
When I click on an item in Fragment A, Fragment B appears in a new View ( = without either action bar nor fragment A)
=> How should I do to display in the same view : Action Bar, Fragment A and Fragment B?
=> I don't understand really how I should configure action bar to appear on top of each view. Is it done in a separate xml? How is it configured? Should we call action bar on top of each activity?
=> I don't understand really why I need 4 levels of xml to display these fragments.
For my code, I used several tutorials from following links but now I'm not able to find an answer:
http://mobile.tutsplus.com/tutorials/android/android-sdk_fragments/
Adding tabs from http://www.devdiv.com/android/docs/guide/topics/ui/actionbar.html
dgn2_action_bar.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">
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/fragment_place">
</LinearLayout>
</LinearLayout>
dgn2_synth_entry.xml
<?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="horizontal" >
<fragment
android:id="#+id/listFragment"
android:layout_width="150dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginTop="?android:attr/actionBarSize"
class="com.android.FragmentA" >
</fragment>
<fragment
android:id="#+id/detailSynthFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
class="com.android.FragmentB" >
<!-- Preview: layout=#layout/details -->
</fragment>
</LinearLayout>
dgn2_synth_detail_layout.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/detailSynthFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.android.FragmentB" />
</LinearLayout>
dgn2_details.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" >
<ListView
android:id="#+id/resultFragmentView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#ffffff"
/>
</LinearLayout>
Dgn2EntryActivity.java
public class Dgn2EntryActivity extends Activity implements Dgn2SynthListFragment.OnSheetSelectedListener
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dgn2_action_bar);
/* Setup Action Bar for tabs */
ActionBar mActionBar = getActionBar();
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
/* add a new tab and set its title text */
ActionBar.Tab tabSynthesis = mActionBar.newTab().setText(R.string.sSynthesisTab);
ActionBar.Tab tabParameter = mActionBar.newTab().setText(R.string.sParameterTab);
/* instantiate fragment for the tab */
ListFragment mSynthesisFragment = new FragmentA();
ListFragment mParamFragment = new FragmentC();
/* Set Listener on Tab Action */
tabSynthesis.setTabListener(new MyTabsListener(mSynthesisFragment));
tabParameter.setTabListener(new MyTabsListener(mParamFragment));
/* Add Tab in Action Bar */
mActionBar.addTab(tabSynthesis);
mActionBar.addTab(tabParameter);
}
public void onSheetSelected(String sheetID, FragmentB viewer)
{
if (viewer == null || !viewer.isInLayout())
{
/*initialise Fragment call */
Intent intent = new Intent(getApplicationContext(),FragmentBActivity.class);
intent.putExtra("value", sheetID);
startActivity(intent);
}
else
{
/* Update Fragment content after a click */
viewer.updateSheet(sheetID);
}
}
protected class MyTabsListener implements ActionBar.TabListener
{
private ListFragment mFragment;
public MyTabsListener(ListFragment mFragment)
{
this.mFragment = mFragment;
}
public void onTabSelected(Tab paramTab,
FragmentTransaction paramFragment)
{
paramFragment.add(R.id.fragment_place, mFragment, null);
}
public void onTabUnselected(Tab paramTab,
FragmentTransaction paramFragment)
{
paramFragment.remove(mFragment);
}
public void onTabReselected(Tab paramTab,
FragmentTransaction paramFragment)
{
}
}
}
FragmentBActivity.java
public class FragmentBActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.dgn2_synth_detail_layout);
/* get Sheet Label */
Bundle extras = getIntent().getExtras();
if (extras != null)
{
String sheetLabel = extras.getString("value");
FragmentB viewer = (FragmentB) getFragmentManager()
.findFragmentById(R.id.detailSynthFragment);
/*Update Fragment Viewer view content*/
viewer.updateSheet(sheetLabel);
}
}
}
FragmentA.java
public class FragmentA extends ListFragment
{
private OnSheetSelectedListener sheetSelectedListener;
public interface OnSheetSelectedListener
{
public void onSheetSelected(String sheetID, FragmentB viewer);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
String[] values = new String[] { GLOBAL_SYNTHESIS_LABEL, SYNTHESIS1_LABEL};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
String item = (String) getListAdapter().getItem(position);
FragmentB viewer = (FragmentB) getFragmentManager().findFragmentById(R.id.detailFragment);
sheetSelectedListener.onSheetSelected(item, viewer);
}
}
FragmentB.java
public class FragmentB extends ListFragment
{
Context mContext;
Dgn1DataListClass allResults = new Dgn1DataListClass();
String[] vIhmDgnVarNameList;
Dgn1ResultCouple[] results;
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
updateSheet(GLOBAL_SYNTHESIS_LABEL);
}
public void updateSheet(String sheetLabel)
{
mContext = getActivity();
ListView resultListView =(ListView)getView().findViewById(R.id.resultFragmentView);
if (sheetLabel == GLOBAL_SYNTHESIS_LABEL)
{
/* Displays A list in 2 columns */
vIhmDgnVarNameList = getResources().getStringArray(R.array.ihm_dgn_row1_array);
results = allResults.fillResults(vIhmDgnVarNameList);
ListItemAdapter2 mcqListAdapter = new ListItemAdapter2(mContext,R.layout.ihm_dgn_row_data,results);
setListAdapter(mcqListAdapter);
}
else if (sheetLabel == SYNTHESIS1_LABEL)
{
/* TODO */
}
}
public class ListItemAdapter2 extends ArrayAdapter<Dgn1ResultCouple>
{
/* Lot Of Code working*/
}
}
Thanks for your help

Related

findFragmentById returns null always

I have one MainActivity and two fragments FGames and FGameDetail. I am trying to communicate between them so that when an item is clicked in the FGames it passes GameEntity to MainActivity and it updates the FGameDetail. I have separate layout created for phone and tablet.
In my MainActivity where I am controlling if the FGameDetail fragment exists in the layout update the view. but findFragmentById always returns null for both FGames and FGameDetails.
Here is my layout for Phones and Tablets
layout\activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/games_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.rao.igttest.MainActivity">
<fragment
android:id="#+id/fragment_fGames"
android:name="com.example.rao.igttest.Games.View.FGames"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
layout-large-land\activity_main
<?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">
<fragment
android:id="#+id/fragment_fGames"
android:name="com.example.rao.igttest.Games.View.FGames"
android:layout_width="400dp"
android:layout_height="wrap_content" />
<fragment
android:id="#+id/fragment_fGameDetail"
android:name="com.example.rao.igttest.Games.View.FGameDetail"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity implements FGames.OnGameSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//FGames fGames = new FGames();
//getSupportFragmentManager().beginTransaction().add(R.id.games_container, fGames).commit();
}
#Override
public void onGameSelected(GameEntity gameEntity) {
FragmentManager fragmentManager = getSupportFragmentManager();
FGameDetail gameDetailFrag = (FGameDetail) fragmentManager
.findFragmentById(R.id.fragment_fGameDetail);
Fragment gameFrag = fragmentManager.findFragmentById(R.id.fragment_fGames);
if (gameDetailFrag == null) {
//TODO Open a new intent
} else {
// DisplayFragment (Fragment B) is in the layout (tablet layout),
// so tell the fragment to update
FGameDetail fGameDetail = new FGameDetail();
fGameDetail.updateContent(gameEntity);
}
}
}
Your help and suggestions is much appreciated.
EDIT
FGAMES
#Override
public void initRecyclerView(List<GameEntity> gameEntities) {
gamesAdapter = new GamesAdapter(getActivity(), gameEntities);
rvGames.setAdapter(gamesAdapter);
rvGames.setLayoutManager(new LinearLayoutManager(getActivity()));
}
GamesAdapter
//Constructor
public GamesAdapter(Context context, List<GameEntity> gameEntities) {
layoutInflater = LayoutInflater.from(context);
this.data = gameEntities;
this.context = context;
}
#OnClick(R.id.row_container)
void rowClick(){
//I think as I am creating a new instance here as I dont have referencec to GamesPresenter in adapter as I am calling it directly from FGames
GamesPresenter gamesPresenter = new GamesPresenterImpl();
gamesPresenter.showGameDetail(data.get(getLayoutPosition()));
Toast.makeText(context, "itemClicked " + data.get(getLayoutPosition()), Toast.LENGTH_SHORT).show();
}
GamesPresenterImpl
#Override
public void showGameDetail(GameEntity gameEntity) {
GamesView gamesView = new FGames();
gamesView.onListItemClick(gameEntity);
}
FGames
#Override
public void onListItemClick(GameEntity gameEntity) {
OnGameSelectedListener mListener = new MainActivity();
mListener.onGameSelected(gameEntity);
}
public interface OnGameSelectedListener{
public void onGameSelected(GameEntity gameEntity);
}
MainActivity - OnGameSelected.
#Override
public void onGameSelected(GameEntity gameEntity) {
FragmentManager fragmentManager = getSupportFragmentManager();
FGameDetail gameDetailFrag = (FGameDetail) fragmentManager
.findFragmentById(R.id.fragment_fGameDetail);
Fragment gameFrag = fragmentManager.findFragmentById(R.id.fragment_fGames);
if (gameDetailFrag == null) {
} else {
// DisplayFragment (Fragment B) is in the layout (tablet layout),
// so tell the fragment to update
FGameDetail fGameDetail = new FGameDetail();
fGameDetail.updateContent(gameEntity);
}
}
Are you sure you are not doing new MainActivity().onGameSelected(object)?
If you using the Interactor fragment pattern, you must use the instance of the Activity you already have in the class.
Also, this line dont update the screen cause you creating a new instance of the fragment that will never be added:
FGameDetail fGameDetail = new FGameDetail();
fGameDetail.updateContent(gameEntity);
There is a instance already in screen so:
gameDetailFrag.updateContent(gameEntity);

How to toggle between fragments

I have an app that has 1 Main Activity and 5 main fragments. When the MainActivity is created I create a List containing each of the 5 fragments. The user is presented with a tab bar on the bottom of the screen which he/she can use to navigate between fragments. How do I set this up so as when the user selects a tab, the corresponding fragment is shown without creating a new instance of it? Just want to change the view on the screen to the already created fragment.
I am using a BottomBar from https://github.com/roughike/BottomBar which calls a "onTabSelected" interface method when a tab is pressed.
You can use 5 Fragments with the library you specified like this. The layout file should look like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- This could be your fragment container, or something -->
<FrameLayout
android:id="#+id/contentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomBar" />
<com.roughike.bottombar.BottomBar
android:id="#+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
app:bb_tabXmlResource="#xml/bottombar_tabs" />
</RelativeLayout>
The containing Activity class will replace the Framelayout with Fragment depending on the Fragment selected from the BottomBar View. A simple example
public class Main3Activity extends AppCompatActivity {
private Fragment fragment;
private FragmentManager fragmentManager;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three_tabs);
BottomBar bottomBar = (BottomBar) findViewById(R.id.bottomBar);
bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
#Override
public void onTabSelected(#IdRes int tabId) {
if(tabId == R.id.tab_home){
fragment = new HomeFragment();
}
if(tabId == R.id.tab_favorite){
fragment = new FavoriteFragment();
}
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.contentContainer, fragment).commit();
});
bottomBar.setOnTabReselectListener(new OnTabReselectListener() {
#Override
public void onTabReSelected(#IdRes int tabId) {
Toast.makeText(getApplicationContext(), TabMessage.get(tabId, true), Toast.LENGTH_LONG).show();
}
});
}
}
Then you can create individual Fragment with their content like below
public class FavoriteFragment extends Fragment {
public FavoriteFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_favorite, container, false
);
}
}

Converting ActivityGroup app to use Fragments/FragmentGroup

I have an app that I desperately need to convert from using the old ActivityGroup class to Fragments. I'm not sure how to go about it though. Below is a sample of the code I use now. Could anyone provide some insight into what steps I should take to start switching it over to use Fragments / FragmentManager instead?
Main.java
public class Main extends TabActivity implements OnTabChangeListener {
public static TextView txtViewHeading;
public static Button btnBack;
public static ImageButton btnShare;
public static Main mainActivity;
public static Boolean isVisible = false;
private GoogleCloudMessaging gcm;
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainActivity = this;
NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, PushHandler.class);
registerWithNotificationHubs();
//reference headings text & button for access from child activities
txtViewHeading = (TextView) findViewById(R.id.txtViewHeading);
btnBack = (Button) findViewById(R.id.btnBack);
btnShare = (ImageButton) findViewById(R.id.btnShare);
// Update the font for the heading and back button
Typeface arialTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/arial.ttf");
Typeface myriadTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/myriad.ttf");
txtViewHeading.setTypeface(myriadTypeface);
btnBack.setTypeface(arialTypeface);
Resources res = getResources();
TabHost tabsNavigation = getTabHost();
// Set up the views for each tab - custom view used for Badge icon
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Set up my tabs...each one looks similar to this
View statusTabView = inflater.inflate(R.layout.tab, null);
ImageView statusTabIcon = (ImageView) statusTabView.findViewById(R.id.tabIcon);
statusTabIcon.setImageResource(R.drawable.tab_first);
TextView statusTabText = (TextView) statusTabView.findViewById(R.id.tabText);
statusTabText.setText("Status");
statusTabText.setTypeface(arialTypeface);
statusTabBadge = (TextView) statusTabView.findViewById(R.id.tabBadge);
statusTabBadge.setTypeface(arialTypeface);
tabsNavigation.addTab(tabsNavigation.newTabSpec(getResources().getString(R.string.main_tab_status))
.setIndicator(statusTabView)
.setContent(new Intent(this, StatusGroupActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
//Set default tab to Status
tabsNavigation.setCurrentTab(0);
tabsNavigation.setOnTabChangedListener(this);
}
/* Set txtViewHeading text to selected tab text */
#Override
public void onTabChanged(String tabId) {
// TODO Auto-generated method stub
txtViewHeading.setText(tabId);
}
/* Set code to execute when onDestroy method is called */
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
/* Set code to execute when onPause method is called */
#Override
protected void onPause() {
super.onPause();
isVisible = false;
}
/* Set code to execute when onResume method is called */
#Override
protected void onResume() {
super.onResume();
isVisible = true;
}
/* Set code to execute when onStop method is called */
#Override
protected void onStop() {
super.onStop();
isVisible = false;
}
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
ToastNotify("This device is not supported by Google Play Services.");
finish();
}
return false;
}
return true;
}
public void ToastNotify(final String notificationMessage) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Main.this, notificationMessage, Toast.LENGTH_LONG).show();
}
});
}
public void registerWithNotificationHubs()
{
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
}
TabGroupActivity.java
public class TabGroupActivity extends ActivityGroup
{
private ArrayList<String> mIdList;
Button btnBack;
ImageButton btnShare;
TextView txtViewHeading;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
btnBack = Main.btnBack;
btnShare = Main.btnShare;
txtViewHeading = Main.txtViewHeading;
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
if (mIdList == null) mIdList = new ArrayList<String>();
}
/**
* This is called when a child activity of this one calls its finish method.
* This implementation calls {#link LocalActivityManager#destroyActivity} on the child activity
* and starts the previous activity.
* If the last child activity just called finish(),this activity (the parent),
* calls finish to finish the entire group.
*/
#Override
public void finishFromChild(Activity child)
{
try
{
btnShare.setVisibility(View.GONE);
LocalActivityManager manager = getLocalActivityManager();
int index = mIdList.size()-1;
if (index < 1)
{
finish();
return;
}
manager.destroyActivity(mIdList.get(index), true);
mIdList.remove(index);
index--;
String lastId = mIdList.get(index);
Intent lastIntent = manager.getActivity(lastId).getIntent();
Window newWindow = manager.startActivity(lastId, lastIntent);
setContentView(newWindow.getDecorView());
//Set Heading text to current Id
txtViewHeading.setText(getActivityHeading(lastId));
//Set Back button text to previous Id if applicable
btnBack.setVisibility(View.VISIBLE);
//Back button
String backId = "";
if(mIdList.size() > 1)
{
backId = mIdList.get(mIdList.size()-2);
btnBack.setVisibility(View.VISIBLE);
btnBack.setText(getActivityHeading(backId));
txtViewHeading.setPadding(10,0,0,0);
}
else
{
btnBack.setVisibility(View.GONE);
txtViewHeading.setPadding(0,0,0,0);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Starts an Activity as a child Activity to this.
* #param Id Unique identifier of the activity to be started.
* #param intent The Intent describing the activity to be started.
*/
public void startChildActivity(String Id, Intent intent)
{
try
{
btnShare.setVisibility(View.GONE);
Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null)
{
mIdList.add(Id);
setContentView(window.getDecorView());
txtViewHeading.setText(getActivityHeading(Id));
//Back button
String backId = "";
if(mIdList.size() > 1)
{
backId = mIdList.get(mIdList.size()-2);
btnBack.setVisibility(View.VISIBLE);
btnBack.setText(backId);
txtViewHeading.setPadding(5,0,0,0);
}
else
{
btnBack.setVisibility(View.GONE);
txtViewHeading.setPadding(0,0,0,0);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
* from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
//preventing default
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Overrides the default implementation for KeyEvent.KEYCODE_BACK
* so that all systems call onBackPressed().
*/
#Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
onBackPressed();
return true;
}
return super.onKeyUp(keyCode, event);
}
/**
* If a Child Activity handles KeyEvent.KEYCODE_BACK.
* Simply override and add this method.
*/
#Override
public void onBackPressed ()
{
try
{
btnShare.setVisibility(View.GONE);
int length = mIdList.size();
if ( length > 1)
{
Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
current.finish();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Get the correct heading text and language based on activity id
*/
public String getActivityHeading(String id)
{
// method that returns the TEXT for my main heading TextView based on the activity we're on...
}
}
StatusGroupActivity
public class StatusGroupActivity extends TabGroupActivity
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startChildActivity("Status", new Intent(this,Status.class));
}
}
... so basically when my app loads, I get my tabs at the bottom, my header at the top, and the "tab content" in the middle. In my Status activity, I can load another activity from it by using ...
Intent intent = new Intent(getParent(), SomeOtherActivity.class)
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Some Other Activity", intent);
... and it loads the SomeOtherActivity activity into the content area. Hitting back takes me back to the Status screen.
Any pointers, examples and assistance with converting this over to use Fragments is so greatly appreciated. I will gladly donate 500 of my rep. points for a full example.
main.xml (Main Activity Layout file)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
tools:ignore="ContentDescription,HardcodedText" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageSuccess"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:scaleType="matrix"
android:src="#drawable/bg_navbar_blank" />
<com.myproject.android.BgButtonStyle
android:id="#+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="0dp"
android:background="#drawable/back_button"
android:text=""
android:textColor="#color/White"
android:textSize="12sp"
android:visibility="visible"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:padding="5dp"/>
<ImageButton
android:id="#+id/btnShare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:background="#null"
android:src="#drawable/icon_share"
android:visibility="visible"
android:adjustViewBounds="false"
android:scaleType="fitXY"/>
<com.myproject.android.AutoResizeTextView
android:id="#+id/txtViewHeading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingLeft="5dp"
android:text="Status"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="28sp"
android:textStyle="bold"
android:paddingRight="5dp"
android:layout_toEndOf="#id/btnBack"
android:layout_toStartOf="#id/btnShare"
android:layout_centerVertical="true"
android:lines="1"/>
</RelativeLayout>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout>
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-4dp"
android:layout_weight="0"
android:background="#drawable/bg_tabs">
</TabWidget>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
In my current TabGroupActivity class, in the finishFromChild and startChildActivity methods, I am able to call setText on the txtViewHeading TextView element in my main activity layout. Which is the current activities "title". If there is more than 1 activity in the group, the back button shows the previous title. How can I duplicate this in the examples below? The main activity layout there is much different than mine.
First you need to add Design Support Library and AppCompatLibrary into your Project
Add this code into your app gradle
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
layout for activity_main.xml (like main.xml in your code)
<?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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
In above layout ViewPager will provides horizontal layout to display tabs. You can display more screens in a single screen using tabs. You can swipe the tabs quickly as you can.
Root Fragment
<FrameLayout 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:id="#+id/root_frame" >
View for First Fragment
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#ff0"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="#string/first_fragment" />
<Button
android:id="#+id/btn"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:text="#string/to_second_fragment"/>
</RelativeLayout>
View for Second and Individual(s) Fragment.
<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"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Now add a MainActivity(like Main Activity in yours code) under which all this thing will handle.
public class MainActivity extends AppCompatActivity {
private TabGroupAdapter mTabGroupAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ArrayList<Fragment> fragmentList = new ArrayList<Fragment>();
fragmentList.add(new RootFragment());
fragmentList.add(new IndividualFragment1());
fragmentList.add(new IndividualFragment2());
ArrayList<String> name = new ArrayList<String>() {
{
add("Root Tab");
add("Second Tab");
add("Third Tab");
}
};
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mTabGroupAdapter = new TabGroupAdapter(getSupportFragmentManager(),name, fragmentList,);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mTabGroupAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
}
There is one FragmentPagerAdapter defined as mTabGroupAdapter inside MainActivity that will add a different tabs inside a single Layout.
First we bind the mTabGroupAdapter to mViewPager.
TabLayout will act like a TabHost under which Tab will be added by FragmentPagerAdapter.
mViewPager is bind to the Tablayout.
Under MainActivity TabLayout will display the name of Tabs.
TabGroupAdapter
public class TabGroupAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragmentList = new ArrayList<Fragment>();
private ArrayList<String> fragment_name;
public TabGroupAdapter(FragmentManager fm, ArrayList<String> name, ArrayList<Fragment> list) {
super(fm);
this.fragmentList = list;
this.fragment_name = name;
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return fragment_name.get(position);
}
}
In TabGroupAdapter you would pass a List of fragments(or single fragment) and list of fragments name(or single name) as arguments in the Constructor.
IndividualFragment(s) will act like a individual Tab instead of Activity.
RootFragment will be acting as a container for other fragments( First Fragment and Second Fragment)
Root Fragment
public class RootFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.root_fragment, container, false);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.root_frame, new FirstFragment());
fragmentTransaction.commit();
return view;
}
}
First Fragment
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.first_fragment, container, false);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//use the "root frame" defined in
//"root_fragment.xml" as the reference to replace fragment
fragmentTransaction.replace(R.id.root_frame, new SecondFragment());
/*
* allow to add the fragment
* to the stack and return to it later, by pressing back
*/
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
}
Second Fragment
public class SecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
Individual(s) Fragment
public class IndividualFragment1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
public class IndividualFragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
In OnCreateView method you would set a layout of a Tab .
You won't have to use the getTabHost() method.
Let me know if you persist any problem.
Whenever you want to dynamically change or update the Tabs in View Pager just add or remove item from fragmentList and call this method mTabGroupAdapter.notifyDataSetChanged(); inside MainActivity.
Add these dependencies to your project:
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
First change your Main activity must be extended from AppCompatActivity.
Than change your main activity's layout like below:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".Main">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<include
layout="#layout/toolbar_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:tabGravity="fill"
app:tabMaxWidth="0dp"
app:tabIndicatorHeight="4dp"
app:tabMode="fixed"
app:tabIndicatorColor="#android:color/white"
android:background="#color/AppPrimary"/>
</android.support.design.widget.AppBarLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".dashboard.DashboardActivity"
tools:showIn="#layout/activity_dashboard">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
And here's a toolbar layout example. You can customize however you want.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar_main"
style="#style/Widget.MyApp.Toolbar.Solid"
android:layout_width="match_parent"
android:layout_height="#dimen/abc_action_bar_default_height_material"
android:background="#color/AppPrimary"
app:contentInsetEnd="16dp"
app:contentInsetStart="16dp" />
Than you need to create fragments which you'll use in your tabs instead of activities which you use for tabs. In this case this'll your Status Activity if i'm not wrong.
Define a StatusFragment like below:
public class StatusFragment extends Fragment
{
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// this is your Status fragment. You can do stuff which you did in Status activity
}
}
Than you need to define a tabs adapter which you'll bind with your tabs and convert your TabHost to Fragment/Fragment manager type. Titles string array contains strings which you'll show in your tabs indicator. Such as "Status, My Assume Tab, My awesome tab 2
public class DashboardTabsAdapter extends FragmentPagerAdapter {
private String[] mTitles;
public DashboardTabsAdapter(FragmentManager fm, String[] titles) {
super(fm);
this.mTitles = titles;
}
#Override
public Fragment getItem(int position) {
return new StatusFragment();
// You can define some other fragments if you want to do different types of operations in your tabs and switch this position and return that kind of fragment.
}
#Override
public int getCount() {
return mTitles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
}
And finally in your Main activity find your view pager, tabs create a new adapter and bind them.
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
final DashboardTabsAdapter dashboardTabsAdapter = new DashboardTabsAdapter(getSupportFragmentManager(), getResources().getStringArray(R.array.tab_titles));
mViewPagerMain = (ViewPager) findViewById(R.id.viewpager_main);
mViewPagerMain.setOffscreenPageLimit(3);
mViewPagerMain.setAdapter(dashboardTabsAdapter);
tabLayout.setupWithViewPager(mViewPagerMain);
Edit: You'll no longer need TabHost and TabActivity any more. Your tab grup activity will be your ViewPager which handles screen changes and lifecycle of fragments inside. If you need to get this activity from fragments you can use getActivity() method and cast it to your activity and use it's public methods.

Adding a button in an activity within fragments with Actionbarsherlock inside the fragment

So I want to have 3 buttons that always appear throughout fragments. I've got an activity with 3 buttons and a fragment layout that contains a fragment with actionbarsherlock inside. The problem is, the buttons in the activity are not clickable and nothing can be executed in the OnClickListener; but the buttons run just fine if I replace the fragment containing actionbarsherlock with a regular fragment without actionbarsherlock inside. I wonder what's wrong.
Here is my code.
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"
android:paddingBottom="2dp"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/fragment_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/button1" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/fragment_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:text="mission" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button1"
android:layout_alignBottom="#+id/button1"
android:layout_centerHorizontal="true"
android:text="feed" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button2"
android:layout_alignBottom="#+id/button2"
android:layout_alignRight="#+id/fragment_content"
android:text="Profile" />
</RelativeLayout>
MyActivity.java:
public class MyActivity extends SherlockFragmentActivity {
/**
* Called when the activity is first created.
*/
Fragment frg;
ActionBarFragment b;
Button btnmission;
Button btnfeed;
Button btnprofile;
boolean small;
static int previousItem;
int tabname;
private Fragment mVisible = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
previousItem=1;
btnmission = (Button) findViewById(R.id.button1);
btnfeed = (Button) findViewById(R.id.button2);
btnprofile = (Button) findViewById(R.id.button3);
btnmission.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("clicked", "button");
if(previousItem!=1){
Intent intent=new Intent(getBaseContext(),MyActivity.class);
startActivity(intent);
}
previousItem=1;
}
});
btnfeed.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(previousItem!=2){
Intent intent=new Intent(getBaseContext(),MissionFragment.class);
intent.putExtra("class", "Feed");
startActivity(intent);
}
previousItem=2;
}
});
btnprofile.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
private void setupFragments() {
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
frg = (ActionBarFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_content);
if (frg == null) {
frg = new ActionBarFragment();
ft.add(R.id.fragment_content, frg);
}
ft.hide(frg);
ft.commit();
}
private void showFragment(Fragment fragmentIn) {
if (fragmentIn == null) return;
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
if (mVisible != null) ft.hide(mVisible);
ft.show(fragmentIn).commit();
mVisible = fragmentIn;
}
It adds a fragment to the activity and actionbar inside the fragment.
ActionBarFragment.java:
public class ActionBarFragment extends SherlockFragment {
int tabname;
#Override
public void onStart()
{
// TODO Auto-generated method stub
super.onStart();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.empty_view, container, false);
// Getting an instance of action bar
ActionBar actionBar = this.getSherlockActivity().getSupportActionBar();
// Enabling Tab Navigation mode for this action bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Enabling Title
actionBar.setDisplayShowTitleEnabled(true);
// Creating Android Tab
Tab tab1 = actionBar.newTab()
.setText("Nova Missoes")
.setTabListener(new CustomTabListener<ListMission>(this.getSherlockActivity(), "mission list", ListMission.class));
// Adding Android Tab to action bar
actionBar.addTab(tab1);
// Creating Apple Tab
Tab tab2 = actionBar.newTab()
.setText("Missoes Concluidas")
.setTabListener(new CustomTabListener<MissionAccomplished>(this.getSherlockActivity(), "mission accomplished", MissionAccomplished.class));
// Adding Apple Tab to action bar
actionBar.addTab(tab2);
Intent in=getSherlockActivity().getIntent();
tabname=in.getIntExtra("tabname", 0);
Log.i("intent", Integer.toString(tabname));
if(tabname==2){
actionBar.selectTab(tab2);
}
// Orientation Change Occurred
if(savedInstanceState!=null){
int currentTabIndex = savedInstanceState.getInt("tab_index");
actionBar.setSelectedNavigationItem(currentTabIndex);
}
return view;
}
#Override
public void onSaveInstanceState(Bundle outState) {
int currentTabIndex = getSherlockActivity().getSupportActionBar().getSelectedNavigationIndex();
outState.putInt("tab_index", currentTabIndex);
super.onSaveInstanceState(outState);
}
}
No problem with displaying the buttons and the tabs, it's just that the OnClickListener is not called when the program runs.

Error inflating class fragment error

I have a Main activity with two master detail Fragments.I am trying to implement like "Multiple fragments, multiple activities" method.
layout folder
activity_main.xml
<FrameLayout 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=".MoneyActivity"
android:id="#+id/fragment_container" >
<fragment class="com.mysite.money.AFragment"
android:id="#+id/AFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
layout-large folder activity_main.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"
tools:context=".MoneyActivity"
android:id="#+id/fragment_container"
android:orientation="horizontal" >
<fragment class="com.mysite.money.AFragment"
android:id="#+id/AFragment"
android:layout_width="#dimen/action_bar_title_text_size"
android:layout_height="match_parent"/>
<fragment class="com.mysite.money.BFragment"
android:id="#+id/BFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
I got error like below(when run on tablet-layout-large):
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mysite.money/com.mysite.money.MoneyActivity}: android.view.InflateException: Binary XML file line #15: Error inflating class fragment
I checked class names of fragments properly.
I think i got error BFragment
BFragment:
public class BFragment extends SherlockFragment {
String selectedItem="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int size = getArguments().size();
if(size>0)
{
selectedItem = getArguments().getString("position").toString();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
TextView textView=new TextView(inflater.getContext());
textView.setText("Selected Item->"+selectedItem);
return textView;
}
}
OnItemSelected in my mainActivity(Associated with fragment A)
**#Override
public void onItemSelected(String id) {
BFragment displayFrag = (BFragment) getSupportFragmentManager().findFragmentById(new BFragment().getId());
if (displayFrag == null) {
// DisplayFragment (Fragment B) is not in the layout (handset layout),
// so start DisplayActivity (Activity B)
// and pass it the info about the selected item
Intent intent = new Intent(this, BActivity.class);
intent.putExtra("position", id);
Log.i("innodea", "position->"+id);
startActivity(intent);
} else {
// DisplayFragment (Fragment B) is in the layout (tablet layout),
// so tell the fragment to update
//displayFrag.updateContent(id);
}
}**
AFragment:
public class AFragment extends SherlockListFragment {
private View inflate;
private Callbacks mCallbacks = sDummyCallbacks;
private int mActivatedPosition= ListView.INVALID_POSITION;
private static final String STATE_ACTIVATED_POSITION = "activated_position";
public interface Callbacks {
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {#link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
public void onItemSelected(String id) {
}
};
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException(
"Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(getActivity(),android.R.layout.simple_list_item_activated_1,android.R.id.text1, DummyContent.ITEMS));
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState
.getInt(STATE_ACTIVATED_POSITION));
}
}
#Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
#Override
public void onListItemClick(ListView listView, View view, int position,long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(
activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
The exception android.view.InflateException: Binary XML file line: #... Error inflating class fragment might happen if you manipulate with getActivity() inside your fragment before onActivityCreated() get called. In such case you receive a wrong activity reference and can't rely on that.
For instance the next pattern is wrong:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
final View view = inflater.inflate(R.layout..., container, false);
Button button = getActivity().findViewById(R.id...);
button.setOnClickListener(...); - another problem: button is null
return view;
}
Adding Unique ID for the Static Fragment is required. I found it after carefully looking in Logs for error. CLick on below link to see error details:
Error Inspection in logs
No need for FragmentActivity as suggested in many posts. AppCompatActivity is fine.
So, code like below works just fine.
<?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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="Customize your Android: " />
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.android.android_me.ui.MasterListFragment"
android:id="#+id/StaticFragment"/>
</LinearLayout>
Your fragment code is most likely broken and simply crashes on creation which ends in failure of inflation. Plant breakpoints on each fragment onCreateView() and related methods called in during fragment creation or try to instantiate the fragment by hand (new AFragment()) and attaching it to The Layout to see where exactly if fails.
You need to import the Fragment class from android.support.v4.app.Fragment instead of android.app.Fragment.
import android.support.v4.app.Fragment;
And in the XML file of the activity where you intend to use this fragment, you need to use:
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map_fragment"
name="yourpackagname.yourfragmentclass"/>
//package name here, is the name of folder which is in java directory.

Categories

Resources