I'm encountering slow/laggy behaviour when swithcing between frgaments using a drawerlayout. I've read up here on stackoverflow and elsewhere regarding solving this issue and a major piece of advice e.g. as seen here is to populating bits of fragment related views elsewhere hence my question of how best can one do the populating part outside of onCreateView() to avoid the laggy behaviour.
Any help is appreciated.
My code is as follows:
My main activity below:
/*! Main activity class */
public class MainActivity extends ActionBarActivity implements FragListener {
/** Private vars */
private DrawerLayout drawerLayout;
private ListView lvDrawerLayout;
private ActionBarDrawerToggle drawerToggle;
private CharSequence drawerTitle;
private CharSequence title;
private DrawerLayoutAdapter drawerLayoutAdapter;
private List<DrawerLayoutDrawer> lvDrawerLayoutData;
/** Public vars */
public static String TAG = "MainActivity";
public MainActivity mainActivity;
public Display display;
public Typeface officialBoldFont, officialRegularFont;
public TextView actionBarTView, tvActionBarTitle = null;
public Fragment fragment;
//!<
public MainActivity() {
}
//!<
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// getTitle() is part of Activity
title = drawerTitle = getTitle();
// Obtain the normal device display area
display = getWindowManager().getDefaultDisplay();
// Set official font
officialRegularFont = Typeface.createFromAsset(this.getAssets(), "square721extendedreg.ttf");
officialBoldFont = Typeface.createFromAsset(this.getAssets(), "square721extendedbold.ttf");
// Show action bar
getSupportActionBar().show();
// Inflate the custom action bar
LayoutInflater inflator = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View mCustomActionView = inflator.inflate(R.layout.actionbar_layout, null);
tvActionBarTitle = (TextView) mCustomActionView.findViewById(R.id.tv_action_bar_title);
tvActionBarTitle.setTypeface(officialBoldFont);
tvActionBarTitle.setTextColor(Color.parseColor("#000000"));
tvActionBarTitle.setTextSize(14.5f);
getSupportActionBar().setCustomView(mCustomActionView);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(0xffFFCC00));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(false);
// Inflate and customise the drawer layout
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.setDrawerShadow(new ColorDrawable(0xffFF0000), GravityCompat.START);
drawerLayout.setBackgroundResource(R.drawable.bgnd_drawerlayout_default);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_closed) {
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(title);
supportInvalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(drawerTitle);
invalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(drawerToggle);
// Inflate and customise the drawer layout list and drawer layout adapter
lvDrawerLayout = (ListView) findViewById(R.id.lv_drawer);
lvDrawerLayout.setDividerHeight(2);
// Below is the listview's bgnd and is different from bgnd_lv_item_drawerlayout.xml which is the bgnd for the items in this LV
lvDrawerLayout.setBackgroundResource(R.drawable.bgnd_lv_drawerlayout_default);
lvDrawerLayoutData = new ArrayList<DrawerLayoutDrawer>();
lvDrawerLayoutData.add(new DrawerLayoutDrawer("ADMINISTRATION", R.drawable.ic_test));
lvDrawerLayoutData.add(new DrawerLayoutDrawer("FINANCE CALCULATOR", R.drawable.ic_test));
lvDrawerLayoutData.add(new DrawerLayoutDrawer("EXIT", R.drawable.ic_test));
drawerLayoutAdapter = new DrawerLayoutAdapter(this, R.layout.lv_layout_drawer, lvDrawerLayoutData, officialRegularFont, officialBoldFont);
lvDrawerLayout.setAdapter(drawerLayoutAdapter);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
// Call starting fragment
if (savedInstanceState == null) {
callStartingFrag(0);
}
}
//!< Call starting fragment
public void callStartingFrag(int position) {
Bundle args = new Bundle();
fragment = new FragmentOne();
args.putString(" ", lvDrawerLayoutData.get(position).getItemName());
args.putInt(" ", lvDrawerLayoutData.get(position).getImgResID());
fragment.setArguments(args);
FragmentManager frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
lvDrawerLayout.setItemChecked(position, true);
drawerLayout.closeDrawer(lvDrawerLayout);
}
//!< Enable drawer layout
public void enableDrawerLayout() {
getSupportActionBar().setHomeButtonEnabled(true);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
//!< Set custom action bar title
public void setActionBarTitle(String title){
tvActionBarTitle.setText(title);
}
//!< Return MainActivity object
public MainActivity getMainActivity() {
mainActivity = new MainActivity();
return mainActivity;
}
//!< This hook is called whenever an item in your options menu is selected. . The action bar home/up action should open or close the drawer. ActionBarDrawerToggle will take care of this.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
//!< Sync the toggle state after onRestoreInstanceState has occurred. Called when activity start-up is complete (after onStart() and onRestoreInstanceState(Bundle) have been called). Applications will generally not implement this method; it is intended for system classes to do final initialization after application code has run.
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
//!< Pass any configuration change to the drawer toggles. This method should always be called by your Activity's onConfigurationChanged method.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
//!< Call respective fragment
public void selectItem(int position) {
switch (position) {
case 0:
fragment = new FragmentTwo();
break;
case 1:
fragment = new FragmentThree();
break;
case 2:
finish();
break;
default:
break;
}
FragmentManager frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
lvDrawerLayout.setItemChecked(position, true);
drawerLayout.closeDrawer(lvDrawerLayout);
}
}
Drawer layout code:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/lv_drawer"
android:layout_width="240dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#000000"/>
</android.support.v4.widget.DrawerLayout>
Drawer layout listview laout code:
<?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="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:id="#+id/itemLayout">
<TextView
android:id="#+id/tv_itemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
Action bar layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent" >
<TextView
android:id="#+id/tv_action_bar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="15dp"
android:maxLines="1"
android:ellipsize="end"/>
</RelativeLayout>
1st fragment code:
public class FragmentOne extends Fragment {
ImageView ivIcon;
TextView tvAgentID;
public Typeface officialBoldFont, officialRegularFont;
public static final String IMAGE_RESOURCE_ID = "iconResourceID";
public static final String ITEM_NAME = "itemName";
public FragmentOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout_one, container, false);
((MainActivity) getActivity()).enableDrawerLayout();
/*dataList = new ArrayList<DrawerLayoutDrawer>();
dataList.add(new DrawerLayoutDrawer("Frag one list item 1", R.drawable.lv_tempimg2));
((MainActivity) getActivity()).changeDrawerList(dataList, new FragOneClickListener());*/
//
officialRegularFont = Typeface.createFromAsset(getActivity().getAssets(), "square721extendedreg.ttf");
officialBoldFont = Typeface.createFromAsset(getActivity().getAssets(), "square721extendedbold.ttf");
tvAgentID = (TextView) view.findViewById(R.id.tv_agentid);
tvAgentID.setText("TESTING 1 2 3");
tvAgentID.setTypeface(officialBoldFont);
tvAgentID.setTextColor(Color.BLACK);
tvAgentID.setBackgroundColor(Color.WHITE);
tvAgentID.setTextSize(25f);
return view;
}
}
1st fragment layout XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#000000">
<LinearLayout
android:id="#+id/ll_innerloginlayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="20dp"
android:padding="20dp">
<TextView
android:id="#+id/tv_agentid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
2nd fragment code below:
public class FragmentTwo extends Fragment {
ImageView ivIcon;
TextView tvItemName;
public static final String IMAGE_RESOURCE_ID = "iconResourceID";
public static final String ITEM_NAME = "itemName";
private List<DrawerLayoutDrawer> dataList;
public FragmentTwo()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_layout_two, container, false);
//
((MainActivity) getActivity()).setActionBarTitle("Test screen 2");
((MainActivity) getActivity()).enableDrawerLayout();
/*dataList = new ArrayList<DrawerLayoutDrawer>();
dataList.add(new DrawerLayoutDrawer("Frag two list item 2", R.drawable.lv_tempimg2));
((MainActivity) getActivity()).changeDrawerList(dataList, new FragTwoClickListener());*/
ivIcon=(ImageView)view.findViewById(R.id.frag2_icon);
tvItemName=(TextView)view.findViewById(R.id.frag2_text);
tvItemName.setText("TESTING FRAG TWO");
tvItemName.setTextSize(45f);
tvItemName.setTextColor(Color.RED);
tvItemName.setBackgroundColor(Color.BLACK);
return view;
}
}
2nd fragment XML code:
<?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="horizontal"
>
<!--
**************************IMPORTANT***********************************
change this id attribute values as "frag2_icon" and "frag2_text" for
fragment_layout_two.xml and "frag3_icon" and "frag3_text" for
fragment_layout_three.xml
**********************************************************************
-->
<ImageView
android:id="#+id/frag2_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/frag2_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_marginLeft="200dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="12dp"
android:paddingBottom="0dp"/>
</LinearLayout>
3rd fragment code:
public class FragmentThree extends Fragment {
ImageView ivIcon;
TextView tvItemName;
public static final String IMAGE_RESOURCE_ID = "iconResourceID";
public static final String ITEM_NAME = "itemName";
public FragmentThree()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_layout_three, container, false);
ivIcon=(ImageView)view.findViewById(R.id.frag3_icon);
tvItemName=(TextView)view.findViewById(R.id.frag3_text);
tvItemName.setText("TESTING FRAG THREE");
return view;
}
}
3rd fragment XML code:
<?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="horizontal"
>
<!--
**************************IMPORTANT***********************************
change this id attribute values as "frag2_icon" and "frag2_text" for
fragment_layout_two.xml and "frag3_icon" and "frag3_text" for
fragment_layout_three.xml
**********************************************************************
-->
<ImageView
android:id="#+id/frag3_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/frag3_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
1st fragment listener:
public class FragOneClickListener implements ListView.OnItemClickListener {
MainActivity mainActivity;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mainActivity = new MainActivity();
mainActivity.fragOneSelectItem(position);
}
}
2nd fragment listener:
public class FragTwoClickListener implements ListView.OnItemClickListener {
MainActivity mainActivity;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mainActivity = new MainActivity();
mainActivity.fragTwoSelectItem(position);
}
}
Related
I am sorry on the duplicate question but I didn't get answer for my problem.
I create app with TabActivity and also trying to replace one fragment from fragment itself, I read in https://developer.android.com/training/basics/fragments/fragment-ui.html how to do it and i created interface in my fragment that i want to be replace with another,
I implement the interface in my MainActivity and still when running my app it show me container itself.
here is my code:
Main Activity:
public class MainActivity extends FragmentActivity implements New2.OnReplaceFragment {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
public static MainActivity instance = null;
public static MainActivity getInstance(){
return instance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.frame_container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.icon_info);
tabLayout.getTabAt(1).setIcon(R.drawable.icon_heart_rate_sensor_jpg);
tabLayout.getTabAt(2).setIcon(R.drawable.icon_graph_jpg);
instance = this;
}
#Override
public void onReplaceFragment(Class fragmentClass) {
Fragment fragment = null;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container,fragment);
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position) {
case 0:
// New1 tab1 = new New1();
return New1.newInstance();
case 1:
return New2.newInstance();
case 2:
return New3.newInstance();
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
}
return null;
}
}
}
my fragment that I want to replace
Fragment:
public class New2 extends Fragment {
TextView name;
Button change;
ImageView image1;
Animation anime;
private OnReplaceFragment dataPasser;
public static New2 newInstance(){
New2 fragment = new New2();
return fragment;
}
public New2(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_new2, container, false);
name = (TextView) rootView.findViewById(R.id.nameTt);
change = (Button) rootView.findViewById(R.id.changeBtn);
image1 = (ImageView) rootView.findViewById(R.id.image1);
anime = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),R.anim.zoom);
change.setOnClickListener(changeName);
return rootView;
}
View.OnClickListener changeName = new View.OnClickListener() {
#Override
public void onClick(View view) {
image1.startAnimation(anime);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run(){
dataPasser.onReplaceFragment(Result.class);
}
},1000);
}
};
public interface OnReplaceFragment {
public void onReplaceFragment(Class fragmentClass);
}
#Override
public void onAttach(Activity a) {
super.onAttach(a);
try {
dataPasser = (OnReplaceFragment) a;
} catch (ClassCastException e) {
throw new ClassCastException(a.toString() + " must implement onDataPass");
}
}
}
the fragment that i want to display
public class Result extends Fragment {
TextView textView;
Button btnBack;
public static Result instance = null;
public static Result getInstance(){
return instance;
}
public Result() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_result, container, false);
textView = (TextView) v.findViewById(R.id.text11);
btnBack = (Button) v.findViewById(R.id.btnBack);
textView.setText("working!!");
Toast.makeText(getActivity().getApplicationContext(),"working",Toast.LENGTH_LONG).show();
return v;
}
}
Main Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.hercules.tadhosttutrial.MainActivity">
<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:background="#color/red"
android:theme="#style/AppTheme.AppBarOverlay">
<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/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
New2 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="com.example.hercules.tadhosttutrial.New2"
android:background="#color/yellow">
<!-- TODO: Update blank fragment layout -->
<Button
android:id="#+id/changeBtn"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:text="change"/>
<ImageView
android:id="#+id/image1"
android:background="#drawable/icon_complete"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
Result 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:background="#color/colorAccent"
tools:context="com.example.hercules.tadhosttutrial.Result">
<!-- TODO: Update blank fragment layout -->
<Button
android:id="#+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="back"/>
<TextView
android:id="#+id/text11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WORKING"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:textSize="70dp"
/>
</RelativeLayout>
What i mean, is making MainActivity as a main container for all fragments, either with tabs or just a regular fragment,
1- Main Activity XML: remove ViewPager, add a FrameLayout instead (use same id)
2- Create new fragment TabsFragment with this 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="com.example.hercules.tadhosttutrial.New2"
android:background="#color/yellow">
<android.support.v4.view.ViewPager
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
3- Move initializing SectionsPagerAdapter and ViewPager from main activity to TabsFragment:
this part:
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
and this:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.frame_container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.icon_info);
tabLayout.getTabAt(1).setIcon(R.drawable.icon_heart_rate_sensor_jpg);
tabLayout.getTabAt(2).setIcon(R.drawable.icon_graph_jpg);
4- I think moving SectionsPagerAdapter class in a new file is better too.
now if you want default view for app to be the tabs, then in MainActivity at onCreate() show TabsFragment by calling your method:
onReplaceFragment(TabsFragment.class);
now every thing should work fine, because the idea here is to replace the fragment displayed in main activity with another one
in this case TabsFragment, Result, and New2
not to replace viewpager fragments (because as i told you this is managed via the adapter) not by calling replace()
you may need to play around this, it's not a final code, just something to give you idea about it.
I have an activity which hosts two fragments inside a view pager. I used the same layout to inflate those fragments. The layout has two edit texts placed inside a linear layout which is inside a relative layout. The problem is when I switch from fragment A to fragment B, he first edit text has focus in fragment A and when I return back from fragment B to fragment A, instead of the first edit text having focus, the second edit text gets the focus. How to solve it. I provide the layouts and source code below. I have not return any code inside the fragment classes.
Activity:
public class LoginActivity extends BaseActivity {
public static final String selectedTabPosition = "selectedTabPosition";
//Tab tag name
private static String TAB_1_TAG = "Email";
private static String TAB_2_TAG = "Mobile";
private TabLayout mTabLayout;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
TAB_1_TAG = getResources().getString(R.string.tab_email);
TAB_2_TAG = getResources().getString(R.string.tab_mobile);
//Initialise views
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabLayout = (TabLayout) findViewById(R.id.tabs);
//set tab with view pager
setupViewPager(mViewPager);
mTabLayout.setupWithViewPager(mViewPager);
setupTabIcons();
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
dismissKeyboard(mViewPager);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* Adding custom view to tab
*/
private void setupTabIcons() {
LinearLayout tabOne = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.tab_custom, null);
TextView tvIconOne = (TextView) tabOne.findViewById(R.id.tv_tab_title);
tvIconOne.setText(TAB_1_TAG);
mTabLayout.getTabAt(0).setCustomView(tabOne);
setTypeface(tvIconOne, CustomFonts.Prime_regular);
mTabLayout.getTabAt(0).getCustomView().setSelected(true);
LinearLayout tabTwo = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.tab_custom, null);
TextView tvIconTwo = (TextView) tabTwo.findViewById(R.id.tv_tab_title);
tvIconTwo.setText(TAB_2_TAG);
setTypeface(tvIconTwo, CustomFonts.Prime_regular);
mTabLayout.getTabAt(1).setCustomView(tabTwo);
}
/**
* Adding fragments to ViewPager
*
* #param viewPager The view pager
*/
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
LoginFragment loginFragmentEmail = new LoginFragment();
Bundle emailBundle = new Bundle();
emailBundle.putInt(selectedTabPosition, 0);
loginFragmentEmail.setArguments(emailBundle);
LoginFragment loginFragmentMobile = new LoginFragment();
Bundle phoneBundle = new Bundle();
phoneBundle.putInt(selectedTabPosition, 1);
loginFragmentMobile.setArguments(phoneBundle);
adapter.addFrag(loginFragmentEmail, TAB_1_TAG);
adapter.addFrag(loginFragmentMobile, TAB_2_TAG);
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Fragment:
public class LoginFragment extends BaseFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_login, container, false);
return rootView;
}
activity_login.xml:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_title"
android:layout_width="200dp"
android:layout_height="45dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="#dimen/custom_tab_layout_height"
android:layout_below="#+id/iv_title"
android:layout_marginTop="#dimen/spacing_10"
app:tabGravity="fill"
app:tabIndicatorColor="#color/app_color_dark"
app:tabMode="fixed"/>
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="#dimen/divider_height_small"
android:layout_below="#+id/tabs"
android:background="#color/gray_medium"/>
<com.helper.CustomNonSwipeableViewpager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/view"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</RelativeLayout>
fragment_login.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing_50"
android:orientation="vertical">
<EditText
android:id="#+id/et_email"
android:layout_width="match_parent"
android:layout_height="#dimen/spacing_48"
/>
<EditText
android:id="#+id/et_password"
android:layout_width="match_parent"
android:layout_height="#dimen/spacing_48"
android:layout_marginTop="#dimen/spacing_15"/>
</LinearLayout>
</RelativeLayout>
AndroidManifest.xml:
<activity
android:name=".activities.LoginActivity"
android:screenOrientation="portrait"
/>
In the AndrodManifest file, tried the
android:windowSoftInputMode = stateHidden and android:windowSoftInputMode = adjustPan
CustomNonSwipeableViewpager.java:
public class CustomNonSwipeableViewpager extends ViewPager {
public CustomNonSwipeableViewpager(Context context) {
super(context);
}
public CustomNonSwipeableViewpager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
}
ScreenShots:
Before moving to FragmentB:
In Fragment B:
Return back to Fragment A from Fragment B:
You can disable the focus on the EditText during runtime of the fragment:
EditText et_email_view = (EditText) rootView.findViewById(R.id.et_email);
et_email_view.setFocusable(false);
Use requestFocus attribute to your first editText which will always cause that editText to gain focus.
Make following changes in your fragment_login.xml file,
<EditText
android:id="#+id/et_email"
android:layout_width="match_parent"
android:layout_height="#dimen/spacing_48">
<requestFocus />
</EditText>
For example in my case viewPager is covering editText. I set translationZ at editText(translationZ="2") and viewPage(translationZ="1") and it helped me.
I am learning how to use navigation drawer and navigation tab. I created an app that implement a navigation drawer on MainActivity and each item on navigation drawer will replace fragment on MainActivity to the corresponding fragment.
My first fragment provide two navigation tab using SlidingTabLayout and SlidingTabStrip. The other fragments are just a textview.
If I move from the first item to the second item and then back to first item again, my tab still show two tab, but in fact, I can slide more than two times and the content is not shown.
How do I fix this?
What it should be:
After I move to second drawer and then back to first drawer:
What happened after that:
You can see that I can slide more than twice and the content of fragments are not shown.
MainActivity.java
public class MainActivity extends ActionBarActivity {
String titles[] = {"TabsFragment", "TextFragment"};
Fragment fragment[] = {TabsFragment.newInstance(), TextFragment.newInstance()};
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
DrawerLayout drawer;
ActionBarDrawerToggle mDrawerToggle;
static View.OnClickListener drawerItemClickListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mAdapter = new DrawerAdapter(titles);
drawerItemClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
int selectedPos = mRecyclerView.getChildPosition(v);
drawer.closeDrawers();
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, fragment[selectedPos])
.commit();
}
};
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this,
drawer,
toolbar,
R.string.open_drawer,
R.string.close_drawer) {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
supportInvalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
supportInvalidateOptionsMenu();
}
};
drawer.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, fragment[0])
.commit();
}
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize" />
<FrameLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/toolbar"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ffffff"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.DrawerLayout>
TabsFragment.java
public class TabsFragment extends Fragment {
public static Fragment newInstance() {
TabsFragment fragment = new TabsFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tabs, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(new SamplePagerAdapter(getActivity().getSupportFragmentManager(), getActivity().getApplicationContext()));
SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setDistributeEvenly(true);
mSlidingTabLayout.setViewPager(mViewPager);
}
class SamplePagerAdapter extends FragmentPagerAdapter {
private String[] tabTitles = new String[] {"Tab One", "Tab Two"};
private Context context;
public SamplePagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
android.support.v4.app.Fragment[] fragment = {TabOneFragment.newInstance(), TabTwoFragment.newInstance()};
return fragment[position];
}
}
}
fragment_tabs.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=".TabsFragment">
<android.com.drawertab.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/sliding_tabs" />
</RelativeLayout>
TabsOneFragment.java
public class TabOneFragment extends Fragment{
public static TabOneFragment newInstance() {
TabOneFragment fragment = new TabOneFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_one, container, false);
}
}
fragment_tabs_one.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/text"
android:text="TAB ONE" />
</LinearLayout>
TabsTwoFragment.java
public class TabTwoFragment extends Fragment {
public static TabTwoFragment newInstance() {
TabTwoFragment fragment = new TabTwoFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_two, container, false);
}
}
fragment_tabs_two.java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/text"
android:text="TAB TWO" />
</LinearLayout>
TextFragment.java
public class TextFragment extends Fragment {
public static Fragment newInstance() {
TextFragment fragment = new TextFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_text, container, false);
}
}
fragment_text.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/text"
android:text="FRAGMENT TEXT" />
</LinearLayout>
DrawerAdapter.java
public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.ViewHolder> {
private String mNavTitles[];
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView,int ViewType) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.rowText);
itemView.setOnClickListener(MainActivity.drawerItemClickListener);
}
}
public DrawerAdapter(String[] titles) {
mNavTitles = titles;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_item_row, parent, false);
ViewHolder vhItem = new ViewHolder(v, viewType);
return vhItem;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(mNavTitles[position]);
}
#Override
public int getItemCount() {
return mNavTitles.length;
}
}
drawer_item_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="4dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/rowText" />
</LinearLayout>
If you are correct about sliding more times than twice, then you need to set the override method getCount correctly (I realize you know). That's the only issue you need to worry about.
private String[] tabTitles = new String[] {"Tab One", "Tab Two"};
...
#Override
public int getCount() {
return tabTitles.length;
}
Note: I declared tabTitles differently as an array of String "String[]", widely accepted. The other style "tabTitles[]" may not work well with its methods like length.
Looking at your code more closely, I suspect objects TabOneFragment and TabTwoFragment is not working well. Normally override getItem returns the same static Fragment. And of course, I do not see that declaration or code for it.
My suggested try is (from your code):
#Override
public android.support.v4.app.Fragment getItem(int position) {
return TabsFragment.newInstance(position);
}
Note: With the above code, I don't see any use for TabOneFragment and TabTwoFragment, referenced in getItem(int position) in SamplePagerAdapter class. The TextView UI in layout fragment_tab_one.xml is only used for the tab texts. For those texts, the override getPageTitle(int position) can be used and is already coded.
I have successfully set up the a FragmentActivity with FragementPagerAdapter associated with ViewPager to implement two tabbed application .
One of the Tabs namely "Wave" has a text view and a button . All I want is call textview.setText method via the onClick method of button described by its xml attribute .
I do not know where should I initialize my TextView or Button , how can I get the context of Wave tab and where should I write onclick method-
public class InformationShow extends FragmentActivity {
XMLdata dataObject;
ViewPager viewPager;
PagerAdapter adpt;
Fragment temp;
TextView tv;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
viewPager=(ViewPager)findViewById(R.id.pager);
adpt = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adpt);
// temp=adpt.fg.findFragmentById((int)adpt.getItemId(1));
tv=(TextView)findViewById(R.id.graphWaveTextView);
bt = (Button)findViewById(R.id.button1);
}
public void changeText(View v){
tv.setText("It worked ");
}
Adapter Class
public class PagerAdapter extends FragmentPagerAdapter {
int count = 2;
CharSequence namme[] = {"Temperature","Wave"};
XMLdata data;
FragmentManager fg;
public PagerAdapter(FragmentManager fragmentManager ){
super(fragmentManager);
this.fg = fragmentManager;
}
Context context;
#Override
public Fragment getItem(int arg0) {
switch (arg0){
case 0:{
TemperatureGraphFrag temp = new TemperatureGraphFrag();
return temp;
}
case 1:{WaveHeightGraphFrag wave = new WaveHeightGraphFrag();
return wave;
}
}
return null;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return namme[position];
}
}
Fragments Class
public class TemperatureGraphFrag extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.graph_t, container, false);
return view;
}
}
public class WaveHeightGraphFrag extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.graph_sig_wave_height, container, false);
return view;
}
}
fragment_main XML implemented by FragmentActicity
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="#65C2C9"
android:scrollbarSize="5dp"/>
</android.support.v4.view.ViewPager>
Tab 2 Fragment XML graph_sig_wave_height
<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/graphWaveTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_gravity="center"
/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center"
android:onClick="changeText"/>
</LinearLayout>
Tab 1 fragment layout XML graph_t
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/linearTemp"
>
<TextView
android:id="#+id/graphTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="center"
/>
</LinearLayout>
Add the following method to your WaveHeightGraphFrag class:
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
final TextView t = (TextView) view.findViewById(R.id.graphWaveTextView);
Button b = (Button) view.findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
t.setText("It worked ");
}
});
}
This is what you want.
I am having a application which is having four different activities. Now i want to add a navigation drawer in application to navigates those activities. Can any one give an example or tutorial for navigation drawer for different activity with back word compatibility.I have seen example for fragments but I need example for activities.
You need to use appcompact from the Support Library.
Your activity needs to extend ActionBarActivity.
In your Activity
public class MainActivity extends ActionBarActivity {
Import
import android.support.v7.app.ActionBarActivity;
Instead of getActionBar() use getSupportActionbar()
Use Them.AppCompact
Or use ActionBarSherlock library.
https://stackoverflow.com/questions/20071004/add-icon-in-drawerlist-by-actionbarsherlock/20077469#20077469
Example:
MainActivity.java
public class MainActivity extends ActionBarActivity {
// Fields -----------------------------------------------------------------
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
private MenuListAdapter menuAdapter;
private int[] icons;
private Fragment fragment1;
private Fragment fragment2;
private Fragment fragment3;
private CharSequence drawerTitle;
private CharSequence title;
private final String[] titles = new String[]{
"Title Fragment #1",
"Title Fragment #2",
"Title Fragment #3"
};
private final String[] subtitles = new String[]{
"Subtitle Fragment #1",
"Subtitle Fragment #2",
"Subtitle Fragment #3"
};
// Lifecycle Callbacks ----------------------------------------------------
#Override
protected void onCreate(Bundle savedInstanceState) {
// Base implemenation
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Instantiate the fragments
fragment1 = new Fragment1();
fragment2 = new Fragment2();
fragment3 = new Fragment3();
// Get the title from this activity
title = drawerTitle = getTitle();
// Get the icons from the drawables folder
icons = new int[]{
R.drawable.action_about,
R.drawable.action_settings,
R.drawable.collections_cloud
};
// Get the drawer layout from the XML file and the ListView inside it
drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
drawerList = (ListView)findViewById(R.id.listview_drawer);
// Set a custom shadow over that overlays the main content
// when the drawer opens
drawerLayout.setDrawerShadow(
R.drawable.drawer_shadow, GravityCompat.START);
// Pass the string arrays to the MenuListAdapter, set the drawer
// list adapter to it and set up its click listener
menuAdapter = new MenuListAdapter(
MainActivity.this, titles, subtitles, icons);
drawerList.setAdapter(menuAdapter);
drawerList.setOnItemClickListener(new DrawerItemClickListener());
// Enable the action bar to have up navigation
getSupportActionBar().setHomeButtonEnabled(true);
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Allow the the action bar to toggle the drawer
drawerToggle = new ActionBarDrawerToggle(
this,
drawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close){
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
}
public void onDrawerOpened(View view){
getSupportActionBar().setTitle(drawerTitle);
super.onDrawerOpened(view);
}
};
drawerLayout.setDrawerListener(drawerToggle);
// If this is the first time opening this activity,
// start with loading fragment #1
if (savedInstanceState == null){
selectItem(0);
}
}
// Methods ----------------------------------------------------------------
#Override
public boolean onOptionsItemSelected(MenuItem item){
// If the user has pressed the action bar icon
if (item.getItemId() == android.R.id.home){
// If the drawer is open, close it; vice versa
if (drawerLayout.isDrawerOpen(drawerList)){
drawerLayout.closeDrawer(drawerList);
} else {
drawerLayout.openDrawer(drawerList);
}
}
// Finish by letting the super class do the rest
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState){
// Call the super implementation and synchronize the drawer
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig){
// Call the super implemenation on this activity
// and the drawer toggle object
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
private void selectItem(int position){
// Create a new fragment transaction and start it
FragmentTransaction fragTran = getSupportFragmentManager()
.beginTransaction();
// Locate the position selected replace the content view
// with the fragment of the number selected
switch (position){
case 0:{
fragTran.replace(R.id.content_frame, fragment1);
break;
}
case 1:{
fragTran.replace(R.id.content_frame, fragment2);
break;
}
case 2:{
fragTran.replace(R.id.content_frame, fragment3);
break;
}
}
// Commit the transaction and close the drawer
fragTran.commit();
drawerList.setItemChecked(position, true);
drawerLayout.closeDrawer(drawerList);
}
public void setTitle(CharSequence title){
// Save the passed in title and set the action bar title
this.title = title;
getSupportActionBar().setTitle(title);
}
// Classes ----------------------------------------------------------------
private class DrawerItemClickListener
implements ListView.OnItemClickListener{
#Override
public void onItemClick(
AdapterView<?> parent,
View view,
int position,
long id) {
// When clicked, select open the appropriate fragment
selectItem(position);
}
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ListView
android:id="#+id/listview_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"/>
</android.support.v4.widget.DrawerLayout>
public class MenuListAdapter extends BaseAdapter {
// Fields -----------------------------------------------------------------
private Context mcontext;
private String[] titles;
private String[] subtitles;
private int[] icons;
private LayoutInflater inflater;
// Constructor ------------------------------------------------------------
public MenuListAdapter(
Context context,
String[] titles,
String[] subtitles,
int[] icons){
mcontext = context;
this.titles = titles;
this.subtitles = subtitles;
this.icons = icons;
inflater = (LayoutInflater)mcontext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
// Accessors --------------------------------------------------------------
#Override
public int getCount(){
return titles.length;
}
#Override
public Object getItem(int position){
return titles[position];
}
#Override
public long getItemId(int position){
return position;
}
// Methods ----------------------------------------------------------------
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder;
// Only inflate the view if convertView is null
if (convertView == null){
viewHolder = new ViewHolder();
if(inflater!=null)
{
convertView = inflater.inflate(
R.layout.drawer_list_item, parent, false);
viewHolder.txtTitle = (TextView)convertView.findViewById(
R.id.title);
viewHolder.txtSubtitle = (TextView)convertView.findViewById(
R.id.subtitle);
viewHolder.imgIcon = (ImageView)convertView.findViewById(
R.id.icon);
// This is the first time this view has been inflated,
// so store the view holder in its tag fields
convertView.setTag(viewHolder);
}
else
{
Log.i("........",""+null);
}
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
// Set the views fields as needed
viewHolder.txtTitle.setText(titles[position]);
viewHolder.txtSubtitle.setText(subtitles[position]);
viewHolder.imgIcon.setImageResource(icons[position]);
return convertView;
}
// Classes ----------------------------------------------------------------
static class ViewHolder {
TextView txtTitle;
TextView txtSubtitle;
ImageView imgIcon;
}
}
drawr_list_item.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:background="#android:color/darker_gray"
android:orientation="horizontal"
style="?attr/dropdownListPreferredItemHeight" >
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical|left"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
style="?attr/spinnerDropDownItemStyle"/>
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
style="?attr/spinnerDropDownItemStyle"/>
</LinearLayout>
</LinearLayout>
fragment1.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" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
fragment2.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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/Fragment2"/>
</RelativeLayout>
fragment3.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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/Fragment3"/>
</RelativeLayout>
Fragment1.java
public class Fragment1 extends Fragment {
String[] titles={"A","B","C"};
#Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment1, container, false);
ListView lv = (ListView) rootView.findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,titles);
lv.setAdapter(adapter);
return rootView;
}
}
Fragment2.java
public class Fragment2 extends Fragment {
#Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment2, container, false);
return rootView;
}
}
Fragment3.java
public class Fragment3 extends Fragment {
#Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment3, container, false);
return rootView;
}
}
Add theme in manifest
android:theme="#style/Theme.AppCompat"
Snap
A new version of the v4 support library (release 13) which contains support for the Navigation Drawer pattern.
Check out the below tutorial Links for Navigation Drawer which provides the compatibility library of Navigation Drawer with the implementation in it.
1) Sherlock Navigation Drawer
2) NavDrawerExampleAppCompat-v7
3) Navigation Drawer in Android
4) Create Navigation Drawer
Hope this will help you.
Navigation Drawer which is implemented in the using DrawerLayout , if not using any externel library, is avaliable in the Android Support Package. So it can be using about API level 4 which Donut(1.6). Use this link for more info DrawerLayout