How to make my slow ViewPager to work faster - android

I've created Activity to handle ViewPager. At the beginning it was working fine, but then I had to add some more code, to make it refresh my pages while selecting them. I've handled it by calling onResume() method with every page change.
I've optimized my Fragments, cleared unnecessary code (inside onResume()) in each of them, but this give no result. That's how my Activity looks like:
public class MainTabsActivity extends AppCompatActivity implements FullList.OnListFragmentInteractionListener, AcceptedList.OnListFragmentInteractionListener, StartedList.OnFragmentInteractionListener {
private static final int NUM_TABS = 3;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_tabs);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
Fragment fragment = ((SectionsPagerAdapter)mViewPager.getAdapter()).getFragment(i);
if (fragment != null) {
Log.e("PAGE SELECTED", " " + i);
tabLayout.getTabAt(i).select();
fragment.onResume();
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
Intent i = getIntent();
int pageNum = i.getIntExtra("pagenumber", 0);
mViewPager.setCurrentItem(pageNum);
tabLayout.getTabAt(pageNum).select();
mViewPager.invalidate();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main_tabs, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onListFragmentInteraction(DummyContent.DummyItem item) {
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
mFragmentTags = new HashMap<>();
mFragmentManager = fm;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return getString(R.string.tab_text_1);
case 1:
return getString(R.string.tab_text_2);
case 2:
return getString(R.string.tab_text_3);
}
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FullList tab1 = new FullList();
return tab1;
case 1:
AcceptedList tab2 = new AcceptedList();
return tab2;
case 2:
StartedList tab3 = new StartedList();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return NUM_TABS;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
Object obj = super.instantiateItem(container, position);
if (obj instanceof Fragment) {
Fragment f = (Fragment) obj;
String tag = f.getTag();
mFragmentTags.put(position, tag);
}
return obj;
}
public Fragment getFragment(int position) {
String tag = mFragmentTags.get(position);
if (tag == null) return null;
return mFragmentManager.findFragmentByTag(tag);
}
}
}
I've added code, to call onResume() method, but funny thing is that the Fragments are loading so long only while I open this Activity from another, but not while scrolling between pages (everything works smoothly then), before changes everything was fine.
Is there any way to make this work faster?

You don't need to write onPageSelected code to change your tab selection.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager); // this will synchronize our tablayout with your viewpager
You should not call onResume directly, this is a system event and a call to this void
is not recommended.
Also, in your case, no need to call mViewPager.invalidate()

Related

add callback listener in each viewpager fragment

I've 2 fragments in viewpager and I want to add callback methods using interface in both. I add the interface listener while initiating fragments in viewpager adapter but only the last fragment's is being called. That's why when I click on the MainActivity's menu option, only the Toast in MyFragB is being called even if MyFragA is showing.
Both Fragments... Only Activity calling MyFragB Toast is showing when wither fragment is opened
public class MyFragA extends Fragment implements FragmentCaller {
private TextView myTxt;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.myfraga, container, false);
}
#Override
public void CallFragment() {
if(getActivity()!=null)
Toast.makeText(getActivity(), "Activity calling MyFragA", Toast.LENGTH_SHORT).show();
}
}
public class MyFragB extends Fragment implements FragmentCaller{
private TextView myTxt;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.myfragb, container, false);
}
#Override
public void CallFragment() {
if(getActivity()!=null)
Toast.makeText(getActivity(), "Activity calling MyFragB", Toast.LENGTH_SHORT).show();
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
TabLayout tabs;
ViewPager viewpager;
FragmentCaller fragListerner = null;
public interface FragmentCaller {
void CallFragment();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabs = (TabLayout)findViewById(R.id.tabs);
viewpager = (ViewPager)findViewById(R.id.viewpager);
SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(this, getSupportFragmentManager());
viewpager.setAdapter(adapter);
tabs.setupWithViewPager(viewpager);
} // onCreate ends
public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
public SimpleFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
// This determines the fragment for each tab
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new MyFragA();
fragListerner = (FragmentCaller) fragment;
return fragment;
} else if (position == 1){
fragment = new MyFragB();
fragListerner = (FragmentCaller)fragment;
return fragment;
}
return null;
}
// This determines the number of tabs
#Override
public int getCount() {
return 2;
}
// This determines the title for each tab
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
switch (position) {
case 0:
return mContext.getString(R.string.fraga);
case 1:
return mContext.getString(R.string.fragb);
default:
return null;
}
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.callback, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.call:
if(fragListerner!=null){
if(fragListerner instanceof MyFragA){
fragListerner.CallFragment();
}else if(fragListerner instanceof MyFragB){
fragListerner.CallFragment();
}
}
break;
}
return true;
}
}
I used rick's answer from here.
public class MainActivity extends AppCompatActivity {
TabLayout tabs;
ViewPager viewpager;
public static int currentFrag=0;
SimpleFragmentPagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabs = (TabLayout)findViewById(R.id.tabs);
viewpager = (ViewPager)findViewById(R.id.viewpager);
adapter = new SimpleFragmentPagerAdapter(this, getSupportFragmentManager());
viewpager.setAdapter(adapter);
tabs.setupWithViewPager(viewpager);
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
System.out.println("sammy_current_position: "+position);
currentFrag = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
} // onCreate ends
public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
public SimpleFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new MyFragA();
} else if (position == 1){
return new MyFragB();
}
return null;
}
#Override
public int getCount() {
return 2;
}
// This determines the title for each tab
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
switch (position) {
case 0:
return mContext.getString(R.string.fraga);
case 1:
return mContext.getString(R.string.fragb);
default:
return null;
}
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.callback, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.call:
if(currentFrag == 0) {
MyFragA frag1 = (MyFragA)viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem());
frag1.specialCase();
}
break;
}
return true;
}
}
but only the last fragment's is being called
Of Course ! because at pos == 0 you are setting fragListerner = (FragmentCaller) fragment then at again in pos == 1 you re-set fragListerner = (FragmentCaller)fragment;. So this condition, fragListerner instanceof MyFragB will always be true!
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new MyFragA();
fragListerner = (FragmentCaller) fragment;
return fragment;
} else if (position == 1){
fragment = new MyFragB();
fragListerner = (FragmentCaller)fragment;
return fragment;
}
return null;
}
So, you are trying to communicate from activity to fragment
okay, if you still want to use interfaces, you can do it like that:
create an instance of your interface for each fragment! and in getItem assign them both,
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new MyFragA();
fragAListerner = (FragmentCaller) fragment;
return fragment;
} else if (position == 1){
fragment = new MyFragB();
fragBListerner = (FragmentCaller)fragment;
return fragment;
}
return null;
}
But, there is an easier way to call fragment's methods from it's parent activity, which is like follows, for ex:
Fragment fragment = adapter.getItem(0); // MyFragA is at pos 0
fragment.<specific_function_name>();
Or, by using it's id!
MyFragA fragment = (MyFragA) getFragmentManager().findFragmentById(R.id.MyFragAId);
fragment.<specific_function_name>();
Or, by using it's tag!
MyFragA fragment = (MyFragA) getFragmentManager().findFragmentByTag("MyFragATag");
fragment.<specific_function_name>();

Android - TabLayout - Navigation with RecyclerView Items

I have a Tabbed Activity with 3 Tabs. On each Tab are RecyclerViews with some list items. If you click on an item a new fragment should open and there should appear a Back-Button in the toolbar. My current screen looks like this:
And now I will show you my code. At first MainActivity.java with the TabLayout:
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Pflege");
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.tab_icon_pflege);
tabLayout.getTabAt(1).setIcon(R.drawable.tab_icon_dokumentation);
tabLayout.getTabAt(2).setIcon(R.drawable.tab_icon_probleme);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switch(tab.getPosition()) {
case 0:
mViewPager.setCurrentItem(0);
toolbar.setTitle("Pflege");
break;
case 1:
mViewPager.setCurrentItem(1);
toolbar.setTitle("Daten");
break;
case 2:
mViewPager.setCurrentItem(2);
toolbar.setTitle("Probleme");
break;
default:
mViewPager.setCurrentItem(tab.getPosition());
toolbar.setTitle("Pflege");
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
Tab1Pflege tab1 = new Tab1Pflege();
return tab1;
case 1:
Tab2Dokumentation tab2 = new Tab2Dokumentation();
return tab2;
case 2:
Tab3Probleme tab3 = new Tab3Probleme();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Pflege";
case 1:
return "Daten";
case 2:
return "Probleme";
}
return null;
}
}
}
Here is the Fragment for the first tab with the RecyclerView:
public class Tab1Pflege extends Fragment {
private RecyclerView recyclerView;
private RecyclerView.Adapter rvAdapter;
private RecyclerView.LayoutManager rvLayoutManager;
private ArrayList<String> listItems;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1_pflege, container, false);
listItems = new ArrayList<>();
listItems.add("Test1");
listItems.add("Test2");
listItems.add("Test3");
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
rvLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(rvLayoutManager);
rvAdapter = new RvAdapter(listItems);
recyclerView.setAdapter(rvAdapter);
return rootView;
}
}
And here is my RecyclerView Adapter:
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> {
ArrayList<String> listItems;
public RvAdapter (ArrayList<String> listItems){
this.listItems = listItems;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item_layout, null);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.itemTitle.setText(listItems.get(position));
holder.itemImage.setImageResource(R.drawable.ic_keyboard_arrow_right);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(listItems.get(position));
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView itemTitle;
ImageView itemImage;
public MyViewHolder(View itemView){
super(itemView);
itemTitle = (TextView) itemView.findViewById(R.id.itemTitle);
itemImage = (ImageView) itemView.findViewById(R.id.itemImage);
}
}
}
In this class is an onClickListener for clicking on a list item. And there I want to open a new fragment for example for Test1. On top of that there should appear a Back-Button in the toolbar to navigate back to the Tab1 Overview with the RecyclerView. But I have no idea how to do that. Can someone help me with it?
In onClick, you can do something like this (to load another fragment)
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
Fragment fragment = // TODO: initialise your fragment 'fragment'
mFragments.push(fragment);
// Animation, if need it
// trans.setCustomAnimations(R.anim.right_in, R.anim.left_out,
// R.anim.right_out, R.anim.left_in);
// _container is the id of 'fragment' container in the your xml
trans.replace(R.id._container, fragment);
// variable to identify this fragment, and title of the page as well
String name = // TODO: initialise
trans.addToBackStack(name);
trans.commit();
getSupportActionBar().setTitle(name);
and in onCreate of your activity, setup listener for back stack changes.
FragmentManager manager = getSupportFragmentManager();
manager.addOnBackStackChangedListener(mBackStackListener);
and you can change back icon in
private OnBackStackChangedListener mBackStackListener = new OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
FragmentManager manager = getSupportFragmentManager();
int count = manager.getBackStackEntryCount();
if(count > 0) {
// TODO: Show back icon
} else {
// TODO: Other icon
}
}
};

call method from activity in all fragment instance

I have PengaduanHomeActivity.class with 3 tabs using same Fragment PengaduanFragment.class like here :
public class PengaduanHomeActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detail_profile_user);
appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
actionbar = getSupportActionBar();
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setHomeButtonEnabled(true);
tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(7);
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
tabLayout.setupWithViewPager(mViewPager);
appBarLayout.addOnOffsetChangedListener(this);
}
int index = 0;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
index = i;
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (index == 0) {
PengaduanFragment.enableRefreshLayout(true);
} else {
PengaduanFragment.enableRefreshLayout(false);
}
break;
}
return super.dispatchTouchEvent(ev);
}
public class PagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES =
{"News Task", "Task On Progress", "Completed Task"};
private Bundle bundle;
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return PengaduanFragment.newInstance("0");
case 1:
return PengaduanFragment.newInstance("1");
case 2:
return PengaduanFragment.newInstance("2");
default:
return null;
}
}
}
in code above, i call method in PengaduanFragment
public static void enableRefreshLayout(boolean b) {
mSwipeRefreshLayout.setEnabled(b);
}
but method just called in last PengaduanFragment with position 2. Other PengaduanFragment with position 0 or 1, not called. So how to Called method enableRefreshLayout in all Fragment ? thaks
You should create an interface that declares the method you want to use:
public interface IMyInterface {
public void myMethod();
}
Then, each fragment you have should implement this method:
public class MyFragment extends Fragment implements IMyInterface {
//Fragment code
public void myMethod() {
//Method code
}
}
Finally, make your adapter have a collection of this interface and loop over it when invoked by the activity
public class MyAdapter extends FragmentPagerAdapter {
//Collection of fragments
Fragment[] fragments;
//Adapter code
public void invokeMe(){
//Loop through each fragment
if (fragment instanceof IMyInterface) {
fragment.myMethod();
}
}
}
You should then be able to call invokeMe and have the adapter delegate to the right fragments the right behaviour. Just be careful of if the fragment instance is still active as per your settings on your ViewPager's current offscreen limit (adjustable by calling setOffscreenPageLimit())

How to count fragments?

I have an activity and pager adapter in it which displays 3 fragments. The fragments are shuffled. I need to know the number of each page when I am swiping through them and that number needs to be displayed in a textView. For example, when I am in the first page number 1 is displayed, second page - number 2 and so on.
PagerAdapter.java
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int arg0) {
return this.fragments.get(arg0);
}
#Override
public int getCount() {
return this.fragments.size();
}
public void setFragments(List<Fragment> fragments) {
this.fragments = fragments;
}
}
mainActivity.java
public class testActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager_adapter);
initialisePaging();
}
private void initialisePaging() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,fragment1.class.getName()));
fragments.add(Fragment.instantiate(this,fragment2.class.getName()));
fragments.add(Fragment.instantiate(this,fragment3.class.getName()));
PagerAdapter mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
Collections.shuffle(fragments, new Random(System.nanoTime()));
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setAdapter(mPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_test, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
If you want to be displaying the number in your fragment, use this
In your Activity
#Override
public Fragment getItem(int position) {
// Here you can add an argument that will be passed to the fragment
// In your case you need to pass the page number
Fragment fragment = this.fragments.get(arg0);
Bundle b = new Bundle();
b.putInt("page_number", position);
fragment.setArguments(b);
return fragment;
}
In you fragment do this
int number;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read the data that Activity passed to us
if (savedInstanceState == null) {
Bundle args = getArguments();
if (args != null) {
number = args.getInt("page_number") + 1;
}
}
else {
number = savedInstanceState.getInt("page_number");
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// Here you need to find your TextView and show the number
View v = inflater.inflate(R.layout.some_layout, container, false);
((TextView) v.findViewById(R.id.someTextView)).setText(String.format("%d", number));
return v;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("page_number", number);
}
If you want to be displaying the number in your Activity, use this
private void initialisePaging() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,fragment1.class.getName()));
fragments.add(Fragment.instantiate(this,fragment2.class.getName()));
fragments.add(Fragment.instantiate(this,fragment3.class.getName()));
PagerAdapter mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
Collections.shuffle(fragments, new Random(System.nanoTime()));
// !!! Change ME!!!!!
textView = (TextView) findViewById(R.id.someTextView);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int i) {
textView.setText("Position: " + i);
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
pager.setAdapter(mPagerAdapter);
}
Use PageChangeListener as:
yourPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position)
{
yourTextView.setText("Page: " + position);
}
... ...
});

Show a detail fragment when clicking an item in a ListFragment in Android Studio

My app has a tab bar that should be visible at all times. The first tab contains a ListFragment. When I click on an item within, it loads a new activity that creates a detail fragment displaying the contents of the object in the list. I would like to display this content without having to start a new activity because it also destroys the tab bar!
Any help would be greatly appreciated!
To illustrate, here are some screenshots and code:
This is the code for the FragmentActivity that creates the tabs:
public class MainFragmentActivity extends FragmentActivity
implements ActionBar.TabListener {
SectionsPagerAdapter sectionsPagerAdapter = null;
ViewPager viewPager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
sectionsPagerAdapter =
new SectionsPagerAdapter
(
getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
}); // End of sectionPageAdapter.
Tab browseTab = actionBar.newTab();
browseTab.setIcon(R.drawable.search);
browseTab.setTabListener(this);
actionBar.addTab(browseTab);
Tab myStuffTab = actionBar.newTab();
myStuffTab.setIcon(R.drawable.my_stuff);
myStuffTab.setTabListener(this);
actionBar.addTab(myStuffTab);
Tab profileTab = actionBar.newTab();
profileTab.setIcon(R.drawable.profile);
profileTab.setTabListener(this);
actionBar.addTab(profileTab);
Tab settingsTab = actionBar.newTab();
settingsTab.setIcon(R.drawable.settings);
settingsTab.setTabListener(this);
actionBar.addTab(settingsTab);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment browseFragment = new BrowseFragment();
Bundle browseArgs = new Bundle();
browseArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
browseFragment.setArguments(browseArgs);
return browseFragment;
case 1:
Fragment myStuffFragment = new MyStuffFragment();
Bundle myStuffArgs = new Bundle();
myStuffArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
myStuffFragment.setArguments(myStuffArgs);
return myStuffFragment;
case 2:
Fragment profileFragment = new ProfileFragment();
Bundle profileArgs = new Bundle();
profileArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
profileFragment.setArguments(profileArgs);
return profileFragment;
case 3:
Fragment settingsFragment = new SettingsFragment();
Bundle settingsArgs = new Bundle();
settingsArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
settingsFragment.setArguments(settingsArgs);
return settingsFragment;
}
return null;
}
// There are always 4 tabs
#Override
public int getCount() {
return 4;
}
// Return a CharSequence for the selected tab
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase();
case 1:
return getString(R.string.title_section2).toUpperCase();
case 2:
return getString(R.string.title_section3).toUpperCase();
case 3:
return getString(R.string.title_section4).toUpperCase();
}
return null;
}
}
} // End of class.
This is the code for the first tab:
public class BrowseFragment extends ListFragment {
public static String sectionNumberKey = "sec_num";
private String activityName = "Browse";
int currentPosition = 0;
List<Listing> listings = new ListingData().getListings();
public BrowseFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BrowseArrayAdapter adapter = new BrowseArrayAdapter(getActivity(),
R.layout.browselist_item,
listings);
setListAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_browse,
container, false);
TextView tv = (TextView) rootView.findViewById(R.id.section_label);
int intSectionNumber = getArguments().getInt(sectionNumberKey);
String numAsString = Integer.toString(intSectionNumber);
tv.setText(numAsString);
activityName += " " + numAsString;
return rootView;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
showDetails(position);
}
void showDetails(int index) {
currentPosition = index;
Intent intent = new Intent();
intent.setClass(getActivity(), BrowseDetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
And here is the code for the Detail Activity:
public class BrowseDetailsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
BrowseDetailFragment details = new BrowseDetailFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}
}
Basicly you just have to use the content of the onCreate method from your BrowseDetailActivity in the showDetails method of your BrowseFragment. In this way, you can drop your BrowseDetailsActivity.
BrowseFragment.java
void showDetails(int index) {
BrowseDetailFragment details = BrowseDetailFragment.newInstance(index);
getChildFragmentManager().beginTransaction().add(details).commit();
}
And use the static newInstance method inside your BrowseDetailFragment like so:
BrowseDetailFragment.java
public class BrowseDetailFragment extends Fragment {
private int position;
public static BrowseDetailFragment newInstance(int position) {
BrowseDetailFragment fragment = new BrowseDetailFragment();
fragment.position = position;
return fragment;
}
public BrowseDetailFragment() {
//Required empty constructor
}
//Lifecycle methods and logics
}
Make sure to provide some navigation option so users can return to your list.

Categories

Resources