I have a ViewPager with 6 screens (mViewPagerMain).
At screen 4 I have another ViewPager inside the other (mViewPagerSub). I disable scrolling for the mViewPagerMain at my CustumViewPager, when mViewPagerSub is used - works great.
Now the problem:
When I scroll through the main pages everything works fine, all things load.
When I scroll back from screen 4 (containing the sub) to screen 2 and back to 4, the first 2 screens inside the sub aren't loaded. If I scroll forth and back in the sub, everything loads correctly.
onCreate:
protected void onCreate(Bundle savedInstanceState) {
mSectionsPagerAdapterMain = new SectionsPagerAdapterMain(getSupportFragmentManager());
mSectionsPagerAdapterSub = new SectionsPagerAdapterSub(getSupportFragmentManager());
mViewPagerMain = (CustomViewPager) findViewById(R.id.pagerMain);
mViewPagerMain.setAdapter(mSectionsPagerAdapter);
}
SectionPagerAdapters: (just like in the google example, same for the sub)
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new SettingsFragment(0);
break;
case 1:
fragment = new SettingsFragment(1);
break;
case 2:
fragment = new SettingsFragment(2);
break;
// and so on...
default:
fragment = new SettingsFragment(0);
}
return fragment;
}
#Override
public int getCount() {
return 6;
}
#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();
// and so on ...
}
return null;
}
}
Settingsfragment: (just like in the google example)
public static class SettingsFragment extends Fragment {
int position = 0;
public SettingsFragment(int position) {
this.position = position;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView;
if (position == 0) {
rootView = inflater.inflate(R.layout.main0, container, false);
main0(rootView);
return rootView;
} else if (position == 1) {
rootView = inflater.inflate(R.layout.main1, container, false);
main1(rootView);
return rootView;
} else if (position == 2) {
rootView = inflater.inflate(R.layout.main2, container, false);
main2(rootView);
return rootView;
}
//...and so on...
}
}
relevant page: main4():
public static void main4(View rootView) {
subView = rootView;
new setAdapterTask().execute();
}
and the async task to load the pager:
private static class setAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void result) {
mViewPagerSub = (CustomViewPager)subView.findViewById(R.id.pagerSub);
mViewPagerSub.setAdapter(mSectionsPagerAdapterSub);
mViewPagerSub.refresh();
}
}
CustomViewPager.refresh():
public void refresh() {
getAdapter().notifyDataSetChanged();
}
I tried to use a PageListener like this, to simulate the scrolling, but it had no effect:
private static class PageListener extends SimpleOnPageChangeListener {
public void onPageSelected(int position) {
currentPage = position;
if (mViewPagerSub != null && currentPage == 3) {
mViewPagerSub.setCurrentItem(5);
} else if (mViewPagerSub != null && currentPage == 4) {
mViewPagerSub.setCurrentItem(0);
}
if (mViewPagerSub != null)
mViewPagerSub.refresh();
}
}
Answering my own question:
This did the trick:
private static class PageListener extends SimpleOnPageChangeListener {
public void onPageSelected(int position) {
currentPage = position;
if(currentPage==4 && mViewPagerSub!=null){
new setAdapterTask().execute();
}
}
}
Related
I want to create a createOrderActivity where has three fragments like Service info, ScheduleInfo, confirmation
the service info fragment has editText
if click NextButton(which is situated CreateOrderActivity) check validation editText first. then move ScheduleFragment page.
if first two pages validation ok then move to Confirmation Fragment page.
Here is the FragmentViewpagerAdapter class
public class FragmentViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public FragmentViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
In CreateOrderActivity class
#Override
public void onPageSelected(int position) {
boolean checkSch= false;
if (position == 1) {
ServiceInfoFragment serviceInfoFragment = new ServiceInfoFragment();
//checking validation from ServiceInfoFragment fragment Class
if (serviceInfoFragment.checkServiceValidation()) {
checkSch = true;
//Toast.makeText(CreateOrderActivity.this, "Validation okay", Toast.LENGTH_SHORT).show();
}else {
checkSch = false;
// Toast.makeText(CreateOrderActivity.this, "Please check validation", Toast.LENGTH_SHORT).show();
pagerCreateOrder.setCurrentItem(position-1);
}
}
if (position == 2) {
if (checkSch){
ScheduleFragment scheduleFragment = new ScheduleFragment();
if (scheduleFragment.checkScheduleValidation()) {
Toast.makeText(CreateOrderActivity.this, "Validation okay", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(CreateOrderActivity.this, "Please check S validation", Toast.LENGTH_SHORT).show();
pagerCreateOrder.setCurrentItem(position-1);
}
}else {
Toast.makeText(CreateOrderActivity.this, "Please check validation", Toast.LENGTH_SHORT).show();
pagerCreateOrder.setCurrentItem(position-2);
}
}
}
//checking checkScheduleValidation() in ScheduleFragment class. return null exception
*bellow mehtod declear in Fragment *
public boolean checkServiceValidation(){
return true;
}
I upload this Image
I used this Reference
I found a solution in my way. I have loaded three fragments in a viewpager. In the second fragment, there is one edittext. on clicking the next button, there is a validation for checking email. On the basis of validation next fragment is loaded. All the Fragments are loaded as singleton . You might have caused null pointer exception , because of multiple instance of fragments.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private SectionsPagerAdapter mSectionsPagerAdapter;
private FragmentTwo fragmentTwo;
private ViewPager mViewPager;
Button back, next;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
back = findViewById(R.id.back);
next = findViewById(R.id.next);
next.setOnClickListener(this);
back.setOnClickListener(this);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.vp_viewpager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
if (i==2){
if (!fragmentTwo.checkEditText()) {
Toast.makeText(getApplicationContext(),"False",Toast.LENGTH_LONG).show();
mViewPager.setCurrentItem(i-1);
return;
}
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
}
private void changeViewPagerPosition(int position) {
int totalCount = mViewPager.getAdapter().getCount();
if (position < 0 || position >= totalCount) {
return;
}
mViewPager.setCurrentItem(position);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public void onClick(View view) {
int currentViewpagerPosition = mViewPager.getCurrentItem();
switch (view.getId()) {
case R.id.back:
changeViewPagerPosition(currentViewpagerPosition - 1);
break;
case R.id.next:
if (currentViewpagerPosition==1){
if (!fragmentTwo.checkEditText()) {
Toast.makeText(getApplicationContext(),"Falsee",Toast.LENGTH_LONG).show();
return;
}
}
changeViewPagerPosition(currentViewpagerPosition + 1);
break;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentOne.newInstance(position);
case 1:
return fragmentTwo=FragmentTwo.getInstance();
case 2:
return FragmentThree.newInstance(position);
default:
return FragmentThree.newInstance(position);
}
}
#Override
public int getCount() {
return 3;
}
}
}
The Fragment 2
public class FragmentTwo extends Fragment {
EditText email;
private static FragmentTwo fragment=null;
public FragmentTwo() {
}
public static FragmentTwo getInstance() {
if (fragment == null){
fragment = new FragmentTwo();
}
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_two, container, false);
return rootView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
email = getView().findViewById(R.id.editText);
}
public boolean emailValidator()
{
Pattern pattern;
Matcher matcher;
final String EMAIL_PATTERN = "^[_A-Za-z0-" +
"9-]+(\\.[_A-Za-z0-9-]+)*#[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
pattern = Pattern.compile(EMAIL_PATTERN);
matcher = pattern.matcher(email.getText().toString());
return matcher.matches();
}
public Boolean checkEditText(){
if (emailValidator()){
return true;
}
return false;
}
}
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>();
I am using a Viewpager inside a fragment and the viewpager is having a listview within its fragment.So when a list item is clicked it is redirected to another fragment in the same activity. So when i come back to my previous fragment(viewpager) the viewpager is blank! why is it so
I am desperate for the solution. Any suggestion would be appreciated.
//tabs inside the fragment
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
/* #Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
return PageFragment.newInstance(position + 1);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
return "TAB " + (position + 1);
}*/
#Override
public Fragment getItem(int position) {
Fragment frag = null;
switch (position) {
case 0:
frag = new Full_Roaster_Fragment();
break;
case 1:
frag = new By_Sport_Fragment();
break;
case 2:
frag = new By_Team_Fragment();
break;
case 3:
frag = new Video_Critique_Fragment();
break;
}
return frag;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
String title=" ";
switch (position){
case 0:
title="Full Roaster";
break;
case 1:
title="By Sport";
break;
case 2:
title="By Team";
break;
case 3:
title="For Video Critique";
break;
}
return title;
}
}
//Child Fragment of Viewpager
public class Full_Roaster_Fragment extends Fragment implements AdapterView.OnItemClickListener {
private View rootView;
public static ListView Analystslist;
public static FullRoasterAdapter full_Roaster_adapter;
public static ArrayList<ics.com.ics_app.Beans.AnalystSearchBean.Teams> analysts_search_arraylist1 = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_full_roaster, container, false);
initialization();
full_Roaster_adapter = new FullRoasterAdapter(getActivity(), ApplicationGlobalClass.analysts_search_arraylist);
full_Roaster_adapter.notifyDataSetChanged();
Analystslist.setAdapter(full_Roaster_adapter);
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
full_Roaster_adapter = new FullRoasterAdapter(getActivity(), ApplicationGlobalClass.analysts_search_arraylist);
full_Roaster_adapter.notifyDataSetChanged();
Analystslist.setAdapter(full_Roaster_adapter);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
Toast.makeText(getActivity(), "Full Roaster on Activity Created", Toast.LENGTH_SHORT).show();
// Populates list with our static array
full_Roaster_adapter = new FullRoasterAdapter(getActivity(), ApplicationGlobalClass.analysts_search_arraylist);
full_Roaster_adapter.notifyDataSetChanged();
Analystslist.setAdapter(full_Roaster_adapter);
Log.e("sizeee",String.valueOf(ApplicationGlobalClass.analysts_search_arraylist.size()));
}
private void initialization() {
Analystslist = (ListView)rootView.findViewById(R.id.Analysts_listview);
Analystslist.setOnItemClickListener(this);
}
#Override
public void onResume() {
super.onResume();
// if (ApplicationGlobalClass.flag) {
Toast.makeText(getActivity(), "full Roaster on Resume", Toast.LENGTH_SHORT).show();
full_Roaster_adapter = new
..
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ApplicationGlobalClass.user_id=ApplicationGlobalClass.analysts_search_arraylist.get(i).get(i).getId();
Log.e("userid",String.valueOf(ApplicationGlobalClass.user_id));
Log.e("userid2",String.valueOf(ApplicationGlobalClass.analysts_search_arraylist.get(i).get(i).getId()));
//here new fragment is calling from this fragment
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new FlexibleSpaceWithImageWithViewPagerTab2Activity()).addToBackStack("profile1").commit();
}
You need to override onBackPressed() in the activity that's hosting the fragments like this:
public void onBackPressed() {
int = count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//additional code
} else {
getFragmentManager().popBackStack();
}
I have ViewPager with 4 pages in my Fragment and Inflating the ListView in pager adapter and it is working fine, now i implemented Load More for the ListView and Load More is working only for the first time automatically when ListView item scrolls end but from the second time on words it is not working when ListView item scrolls end.Please any on help me out on this :).
Following is the code where i implemented load more in my PagerAdapter.
#Override
public Object instantiateItem(ViewGroup container, int position)
{
final View view = getActivity().getLayoutInflater().inflate(R.layout.world_fragment_list, container, false);
listview = (LoadMoreListView) view.findViewById(R.id.listView);
listview.setAdapter(wfadapter);
listview.setOnLoadMoreListener(new LoadMoreListView.OnLoadMoreListener() {
#Override
public void onLoadMore() {
Log.e("Calling: ", "onLoadMore()");
}
}
});
container.addView(view);
return view;
}
I followed this tutorial and i resolved above problem.
Thanks #meynety for Helping me.
I do this in many of project and it's work very fine :
first create your ViewPager class with following code :
public class CategoryFragment extends Fragment {
public static CategoryFragment newInstance() {
return new CategoryFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_category, container, false);
initViews(rootView);
return rootView;
}
private void initViews(View rootView) {
ViewPager mPager = (ViewPager) rootView.findViewById(R.id.vp_pager);
mPager.setOffscreenPageLimit(4);
CategoryAdapter mAdapter = new CategoryAdapter(getChildFragmentManager());
mPager.setAdapter(mAdapter);
PagerSlidingTabStrip mIndicator = (PagerSlidingTabStrip) rootView.findViewById(R.id.vp_indicator);
mIndicator.setTypeface(FontHelper.getInstance(getActivity()).getPersianTextTypeface(), 0);
mIndicator.setViewPager(mPager);
}
private class CategoryAdapter extends FragmentPagerAdapter {
public CategoryAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return AllCategoryFragment.newInstance();
case 1:
return LatestVideoFragment.newInstance();
case 2:
return PopularVideoFragment.newInstance();
default:
return MostLikeVideoFragment.newInstance();
}
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return getResources().getString(R.string.drawer_title_category);
case 1:
return getResources().getString(R.string.drawer_title_latest_video);
case 2:
return getResources().getString(R.string.drawer_title_popular_video);
default:
return getResources().getString(R.string.drawer_title_most_liked_video);
}
}
}
}
Then create your BaseFragment class ( here I just put one of them ) :
public abstract class BaseListFragment extends Fragment implements AdapterView.OnItemClickListener {
protected boolean loadingMore, callingRequest ,isVisibleHint, firstRequest = true;
private PagingListView mListView;
private ProgressView mCircularProgress;
private ProgressView mLinearProgress;
private CustomPage mCustomPage;
private BaseListAdapter mAdapter;
private int mPageRequest = 1;
public abstract String getType();
public abstract String getCategorySlug();
public abstract String getCategoryId();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_base_list, container, false);
initViews(rootView);
if (isVisibleHint && firstRequest) {
firstRequest = false;
enable();
}
return rootView;
}
protected void initViews(View rootView) {
mLinearProgress = (ProgressView) rootView.findViewById(R.id.pvl_loading);
mCircularProgress = (ProgressView) rootView.findViewById(R.id.pvc_loading);
mCircularProgress.start();
mListView = (PagingListView) rootView.findViewById(R.id.lv_paging);
mAdapter = new BaseListAdapter(getActivity());
mListView.setOnItemClickListener(this);
}
public void performSearch() {
callingRequest = true;
if (!loadingMore) {
if (mCircularProgress != null)
mCircularProgress.start();
mCustomPage.setVisibility(View.GONE);
if (mAdapter != null)
mAdapter.removeAllItems();
mPageRequest = 1;
}
if (mPageRequest > 1) {
mLinearProgress.start();
}
ServiceHelper.getInstance().searchQuery(getCategoryId(), getCategorySlug(), null, null, getType(), null, mPageRequest).enqueue(new Callback<List<ShortVideoModel>>() {
#Override
public void onResponse(Response<List<ShortVideoModel>> response) {
callingRequest = false;
processResponse(response);
}
#Override
public void onFailure(Throwable t) {
processResponse(null);
}
});
}
public void resetPerformSearch(boolean callService) {
loadingMore = false;
mPageRequest = 1;
if (callService)
performSearch();
}
private void enable() {
mListView.setPagingableListener(new PagingListView.Pagingable() {
#Override
public void onLoadMoreItems() {
loadingMore = true;
if (!callingRequest)
performSearch();
}
});
mListView.setAdapter(mAdapter);
mListView.setHasMoreItems(true);
}
private void processResponse(Response<List<ShortVideoModel>> response) {
if (response != null && response.body() != null && response.body().size() > 0) {
mListView.onFinishLoading(true, response.body());
} else if (mPageRequest == 1) {
//show error
} else {
mListView.setHasMoreItems(false);
loadingMore = false;
}
mPageRequest++;
//stop loading
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startActivity(VideoDetailsActivity.createIntent(getActivity(), mAdapter.getItem(position).getId()));
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
Log.d("Fragments", "fragment visible: " + getClass().getSimpleName());
isVisibleHint = true;
if (firstRequest && getView() != null) {
firstRequest = false;
enable();
}
}
}
}
Now Just create class which extend BaseFrgament;
You can Also take look at here to my LoadMoreListView
I have a project that needs to have two viewpager, each in a different fragment of the activity.
The architecture something like this
The problem is that when a pager view is inflated, the other isn't.
For example, the fragments 1, 2 and 3 can be accessed by clicking. When I click on the first fragment, it inflates the view pager with its two fragments perfectly, but if I click on the fragment 3, the view pager does not inflate the fragments and also the tabs get slower.
Opening the application process again, by clicking on the fragment 3 first, it works perfectly, but clicking on the first after, this problem happens again.
Already debugged the processes and there is nothing different.
My Activity
public class HomeActivity extends AppCompatActivity implements NavigationFragment.OnNavigationListener{
public NavigationFragment mNavigation;
private String mTagFragmentShowing = "";
private int currentNavigation = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ButterKnife.bind(this);
mNavigation = (NavigationFragment) getFragmentManager().findFragmentById(R.id.manager_navigation);
onNavigationSelected(currentNavigation);
}
#Override
public void onNavigationSelected(int position) {
if (mTagFragmentShowing.equals(String.valueOf(position)))
return;
currentNavigation = position;
mNavigation.setNavigationSelected(position);
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(mTagFragmentShowing);
// Hide last fragment
if (fragment != null && fragment.isVisible()) {
fragmentManager.beginTransaction().hide(fragment).commit();
}
// Show new fragment
mTagFragmentShowing = String.valueOf(position);
fragment = fragmentManager.findFragmentByTag(mTagFragmentShowing);
if (fragment != null && fragment.isHidden()) {
fragmentManager.beginTransaction().show(fragment).commit();
} else if (fragment == null) {
fragmentManager.beginTransaction().add(R.id.manager_content, getFragmentByPosition(position), mTagFragmentShowing)
.setTransition(FragmentTransaction.TRANSIT_NONE).commit();
}
}
private Fragment getFragmentByPosition(int position) {
switch (position) {
case 0:
return new DiscoverFragment();
case 1:
return new UpcomingFragment();
case 2:
return new FeaturesFragment();
case 3:
return new VideosFragment();
case 4:
return new MySongsFragment();
}
return null;
}
My Navigation Fragment. It control the other fragments
public class NavigationFragment extends Fragment implements View.OnClickListener {
public ViewHolder mHolder;
public View mButtonSelected;
public OnNavigationListener mCallback;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.component_navigation, container, false);
ButterKnife.bind(this, view);
initView(view);
return view;
}
public void initView(View view) {
mHolder = new ViewHolder();
mHolder.discover = view.findViewById(R.id.component_navigation_discover);
mHolder.upcoming = view.findViewById(R.id.component_navigation_upcoming);
mHolder.features = view.findViewById(R.id.component_navigation_features);
mHolder.videos = view.findViewById(R.id.component_navigation_videos);
mHolder.mymusic = view.findViewById(R.id.component_navigation_mymusic);
mHolder.discover.setTag(0);
mHolder.upcoming.setTag(1);
mHolder.features.setTag(2);
mHolder.videos.setTag(3);
mHolder.mymusic.setTag(4);
mHolder.discover.setOnClickListener(this);
mHolder.upcoming.setOnClickListener(this);
mHolder.features.setOnClickListener(this);
mHolder.videos.setOnClickListener(this);
mHolder.mymusic.setOnClickListener(this);
mButtonSelected = mHolder.features;
}
public void setNavigationSelected(int position) {
setNavigationButtonSelected(false);
switch (position) {
case 0:
mButtonSelected = mHolder.discover;
break;
case 1:
mButtonSelected = mHolder.upcoming;
break;
case 2:
mButtonSelected = mHolder.features;
break;
case 3:
mButtonSelected = mHolder.videos;
break;
case 4:
mButtonSelected = mHolder.mymusic;
break;
}
setNavigationButtonSelected(true);
}
public void setNavigationButtonSelected(boolean enabled) {
mButtonSelected.setBackgroundColor(enabled ? getResources().getColor(R.color.color_red) : Color.TRANSPARENT);
}
#Override
public void onClick(View view) {
if (view != mButtonSelected) {
mCallback.onNavigationSelected((Integer) view.getTag());
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnNavigationListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnNavigationSelectedListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallback = null;
}
static class ViewHolder {
View discover;
View upcoming;
View features;
View videos;
View mymusic;
}
public interface OnNavigationListener {
public void onNavigationSelected(int position);
}
My Fragments with View Pager
public class MySongsFragment extends Fragment {
private OnFragmentInteractionListener mListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getActivity().getSupportFragmentManager().beginTransaction().add(R.id.mysongs_fragment_container, MySongsViewPagerFragment.newInstance(0)).commit();
return inflater.inflate(R.layout.fragment_my_songs, container, false);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
My View Pager
public class MySongsViewPagerFragment extends Fragment {
private static final int NUM_PAGES = 4;
private String[] tab_names;
private List<String> mTabNames;
private PagerAdapter mPagerAdapter;
public #Bind(R.id.pager)
ViewPager mPager;
public static MySongsViewPagerFragment newInstance(int index) {
MySongsViewPagerFragment fragment = new MySongsViewPagerFragment();
Bundle args = new Bundle();
args.putInt("index", index);
fragment.setArguments(args);
return fragment;
}
#Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = initView(inflater, container);
return view;
}
#NonNull private View initView(LayoutInflater inflater, ViewGroup container) {
View view = inflater.inflate(R.layout.fragment_view_pager_my_songs, container, false);
ButterKnife.bind(this, view);
tab_names = getResources().getStringArray(R.array.tabs_mysongs);
mTabNames = Arrays.asList(tab_names);
mPagerAdapter = new ScreenSlidePagerAdapter(getActivity().getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mPager.onTouchEvent(event);
return false;
}
});
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mPager);
return view;
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override public Fragment getItem(int position) {
switch (position) {
case 0:
return new PlaylistsFragment();
case 1:
return new SongsFragment();
case 2:
return new AlbumsFragment();
case 3:
return new ArtistsFragment();
default:
return new PlaylistsFragment();
}
}
#Override public int getCount() {
return NUM_PAGES;
}
#Override public CharSequence getPageTitle(int position) {
return mTabNames.get(position);
}
}
The problem was activity context in viewpager
In My View Pagers. I change
mPagerAdapter = new ScreenSlidePagerAdapter(getActivity().getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
to
mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter);
The two viewpager used the same context. So when I inflated the first, the other was not inflated because interpreted that already existed an inflated viewpager.
Thanks for the help mcwise for show me the method getChildFragmentManager().