I'm using ViewPager in my app and when I press home button during the interaction with ViewPager, the app crashes and I get this error:
3780-3780/? E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Parcel: unable to marshal value OrdinaryFragment{42000b70 #0 id=0x7f090005 android:switcher:2131296261:0}
at android.os.Parcel.writeValue(Parcel.java:1235)
at android.os.Parcel.writeList(Parcel.java:622)
at android.os.Parcel.writeValue(Parcel.java:1195)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1619)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2245)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:2912)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4895)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
at dalvik.system.NativeStart.main(Native Method)
I know that there's some Serialization problem but I have no idea why I have this problem.
Here's my code:
ViewPager:
public class ViewPagerActivity extends FragmentActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link android.support.v4.view.ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
/**
* DBManager Class for comunicating with DataBase
*/
private DBManager dbManager;
/**
* Fragment ArrayList for ViewPager's adapter input
*/
private ArrayList<Fragment> adapterList;
private ArrayList<String> sectionTitleList;
private long recId;
private MasterDataWithRecIdI masterData;
private static final int NEW_RECORD = -1;
private static final String LAYOUT_ID = "LayoutId";
private static final int NUMBER_OF_PAGES = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbManager = new DBManager();
masterData = (MasterDataWithRecIdI) getIntent().getSerializableExtra("MasterData");
if(savedInstanceState != null) {
ArrayList<Fragment> savedList = (ArrayList<Fragment>) savedInstanceState.getSerializable("Adapter");
initFragments(masterData, savedList);
}else{
initFragments(masterData, null);
}
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(mSectionsPagerAdapter.getCount());
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("Adapter", adapterList);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.viewpager_menu, menu);
return true;
}
/**
* Initializing Fragments and SectionsPagerAdapter
*/
private void initFragments(MasterDataWithRecIdI masterData, ArrayList<Fragment> savedAdapter) {
instantiateTitleArray();
if(savedAdapter == null){
adapterList = new ArrayList<Fragment>();
Fragment fm;
Bundle bundle;
int layoutId = 0;
for (int i = 0; i < 3; i++) {
switch(i) {
case 0:
layoutId = R.layout.client_information_page;
break;
case 1:
layoutId = R.layout.loan_information_page;
break;
case 2:
layoutId = R.layout.additional_information_1_page;
break;
}
bundle = new Bundle();
bundle.putInt(LAYOUT_ID, layoutId);
fm = new OrdinaryFragment();
fm.setArguments(bundle);
adapterList.add(fm);
}
fm = new LastFragment();
adapterList.add(fm);
recId = NEW_RECORD;
if (masterData != null) {
recId = masterData.getRecId();
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), adapterList, sectionTitleList, recId, dbManager);
((LastFragment) fm).setSectionsPagerAdapter(mSectionsPagerAdapter, dbManager);
} else {
recId = NEW_RECORD;
if (masterData != null) {
recId = masterData.getRecId();
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), savedAdapter, sectionTitleList, recId, dbManager);
}
}
OrdinaryFragment:
public class OrdinaryFragment extends Fragment {
private static final String LAYOUT_ID = "LayoutId";
private int layoutId;
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.setRetainInstance(true);
layoutId = getArguments().getInt(LAYOUT_ID);
View rootView = inflater.inflate(layoutId, container, false);
ArrayList<DetailsItemI> list = (ArrayList<DetailsItemI>)getArguments().getSerializable("ViewData");
ViewFillerController viewFiller = new ViewFillerController();
viewFiller.fillTheView(rootView, list);
return rootView;
}
}
SectionsPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter implements Serializable{
private static final int NEW_RECORD = -1;
private ArrayList<Fragment> fragmentList;
private ArrayList<String> sectionTitleList;
private long recId;
private DBManager dbManager;
public SectionsPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragmentList, ArrayList<String> sectionTitleList, long recId, DBManager dbManager) {
super(fm);
this.fragmentList = fragmentList;
this.sectionTitleList = sectionTitleList;
this.recId = recId;
this.dbManager = dbManager;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a OrdinaryFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = this.fragmentList.get(position);
Bundle args;
if (fragment.getArguments() == null) {
args = new Bundle();
}else{
args = fragment.getArguments();
}
args.putInt(OrdinaryFragment.ARG_SECTION_NUMBER, position + 1);
args.putLong("RecordID", recId);
if(recId != NEW_RECORD){
args.putSerializable("ViewData", getTabViewValues(recId, position));
}
if(fragment.getArguments() == null) {
fragment.setArguments(args);
}
return fragment;
}
private ArrayList<DetailsItemI> getTabViewValues(long recId, int tabId){
return dbManager.selectDetailsWithRecIdAndTabId(recId, tabId);
}
#Override
public int getCount() {
return this.fragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
if(sectionTitleList == null){
return "";
}
return this.sectionTitleList.get(position).toUpperCase(l);
}
}
Custom TextView where I use Parcelable:
public class XTextView extends TextView {
private String viewParameter;
public XTextView(Context context, AttributeSet attrs) {
super(context, attrs);
getViewAttributes(context, attrs);
}
public String getXViewParameter(){
return String.valueOf(this.viewParameter);
}
public String getXValue(){
return String.valueOf(this.getText());
}
public void setXValue(String xValue) {
this.setText(xValue);
}
/**
* Getting all attributes of view Id-s.
*
* #param context
* #param attrs
*/
private void getViewAttributes(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.XTextView);
final int N = a.getIndexCount();
for(int i = 0; i < N; i++){
int attr = a.getIndex(i);
switch(attr){
case R.styleable.XTextView_viewParameter:
viewParameter = a.getString(attr);
break;
}
}
a.recycle();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedStateTextView ss = new SavedStateTextView(superState);
ss.stateToSave = String.valueOf(this.getText().toString());
return ss;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
if(!(state instanceof SavedStateTextView)) {
super.onRestoreInstanceState(state);
return;
}
SavedStateTextView ss = (SavedStateTextView) state;
super.onRestoreInstanceState(ss.getSuperState());
this.setText(ss.stateToSave);
}
}
SavedStateTextView class:
public class SavedStateTextView extends View.BaseSavedState {
String stateToSave;
public SavedStateTextView(Parcelable superState) {
super(superState);
}
private SavedStateTextView(Parcel in) {
super(in);
this.stateToSave = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(this.stateToSave);
}
public static final Parcelable.Creator<SavedStateTextView> CREATOR =
new Parcelable.Creator<SavedStateTextView>() {
#Override
public SavedStateTextView createFromParcel(Parcel source) {
return new SavedStateTextView(source);
}
#Override
public SavedStateTextView[] newArray(int size) {
return new SavedStateTextView[size];
}
};
}
I hope there'll be some help.
Thanks in advance.
SOLVED
see answer below.
I Solved My problem.
The Fragments That I was using in my ViewPager weren't Serializable. I just made them implement Serializable Interface and now it works fine.
Related
I have created a Tabbed layout in a Activity. My Activity as following point for consideration
1. Number of tabs depends on sorting type available for a Source object. There can be max three tabs i.e. Top, Latest and popular.
2. Each tab contains a GridView and it should be updated when IntentService gets data
3. User can choose the Source from toolbar
4. When new Source is selected, number of tabs should be according to new Source and GridView should also update accordingly
TabbedActivity
public class TabbedActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager mViewPager;
private List<Source> allSourceItem;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
context = this;
// register broadcast
IntentFilter statusIntentFilter = new IntentFilter(Asset.ARTICLE_BROADCAST_ACTION);
TabbedActivity.ArticleStateReceiver mDownloadStateReceiver = new TabbedActivity.ArticleStateReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(mDownloadStateReceiver, statusIntentFilter);
// set toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// set tab layout
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// set the viewpager
mViewPager = (ViewPager) findViewById(R.id.container);
// set up page listner to viewpager
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
startSetUp(getRecentDisplayedData());
}
public void startSetUp(Source src){
int tabsCount = 3;
setTitle(src.getName());
tabsCount = getNumberOfTabs(src.getSortByAvailableTop(),src.getSortByAvailableLatest(),src.getSortByAvailablePopular());
setTabs(tabsCount);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
mViewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager(),tabsCount,src));
}
// handle menus of activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_tabbed, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SourcesActivity.class);
intent.putExtra("SOURCE_ACTIVITY_ACTION","TABBED");
startActivity(intent);
return true;
}
if(id == R.id.change_src){
//get all selected sources
allSourceItem = Source.getAll();
List<String> listItems = new ArrayList<String>();
for(int i = 0; i < allSourceItem.size(); i++ ){
listItems.add(allSourceItem.get(i).getName());
}
final CharSequence[] items = listItems.toArray(new CharSequence[listItems.size()]);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.chnage_news_source);
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Source.updateRecentDisplayed(allSourceItem.get(item));
restartActivity();
}
});
AlertDialog alert = builder.create();
alert.show();
}
return super.onOptionsItemSelected(item);
}
// for creatting tabs Fragments
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private GridView mGridView;
private ArticleAdapter mArticleAdapter;
private ArrayList<Article> mGridData = new ArrayList<Article>();
private TextView tv;
private static final String ARG_SECTION_NUMBER = "section_number";
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabbed, container, false);
tv = (TextView) rootView.findViewById(R.id.test_tv);
tv.setText("Page counter :: "+getArguments().getInt(ARG_SECTION_NUMBER));
mGridView = (GridView) rootView.findViewById(R.id.article_grid);
update(mGridData);
return rootView;
}
public void update(ArrayList<Article> data){
mArticleAdapter = new ArticleAdapter(getContext(),R.layout.aricle_grid_element,data);
mGridView.setAdapter(mArticleAdapter);
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
int tabsCount;
Source src;
public SectionsPagerAdapter(FragmentManager fm, int tabsCount, Source src) {
super(fm);
this.tabsCount = tabsCount;
this.src = src;
}
#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).
if( position == 0){
runArticleService(position+1);
return PlaceholderFragment.newInstance(position + 1);
}else if (position == 1){
runArticleService(position+1);
return PlaceholderFragment.newInstance(position + 1);
}else if (position == 2){
runArticleService(position+1);
return PlaceholderFragment.newInstance(position + 1);
}
return null;
}
#Override
public int getCount() {
// Show 3 total pages.
return tabsCount;
}
#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;
}
private void runArticleService(int tabNumber){
Intent mServiceIntent = new Intent(getBaseContext(), ArticleService.class);
mServiceIntent.setData(Uri.parse(Asset.getSourceArticleURL(src.getUniqueId(),tabNumber)));
startService(mServiceIntent);
}
}
// broadcast receivers handle
private class ArticleStateReceiver extends BroadcastReceiver
{
private ArticleStateReceiver() {
}
// Called when the BroadcastReceiver gets an Intent it's registered to receive
#Override
public void onReceive(Context context, Intent intent) {
String response = intent.getStringExtra(Asset.ARTICLE_EXTENDED_DATA_TYPE);
String sortType = intent.getStringExtra(Asset.ARTICLE_EXTENDED_DATA_SORT);
if(sortType.equals("TOP")){
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
PlaceholderFragment placeholderFragment = (PlaceholderFragment) sectionsPagerAdapter.getItem(0);
placeholderFragment.update(Asset.getArticleObjectFromJSON(response.toString()));
}else if(sortType.equals("LATEST")){
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
PlaceholderFragment placeholderFragment = (PlaceholderFragment) sectionsPagerAdapter.getItem(1);
placeholderFragment.update(Asset.getArticleObjectFromJSON(response.toString()));
}else if(sortType.equals("POPULAR")){
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
PlaceholderFragment placeholderFragment = (PlaceholderFragment) sectionsPagerAdapter.getItem(2);
placeholderFragment.update(Asset.getArticleObjectFromJSON(response.toString()));
}
}
}
// Extra methods
private int getNumberOfTabs(boolean top, boolean latest, boolean popular ){
if( top && latest && popular){
return 3;
}else if( top && latest && !popular ){
return 2;
}else if( top && !latest && !popular ){
return 1;
}else{
return 1;
}
}
private void setTabs(int tabCount){
tabLayout.removeAllTabs();
if(tabCount == 3){
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_1_text)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_2_text)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_3_text)));
}
if(tabCount == 2){
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_1_text)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_2_text)));
}
if(tabCount == 1){
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_1_text)));
}
}
private Source getRecentDisplayedData(){
Source src = Source.getRecentDisplayed();
if(src!=null){
return src;
}else{
src = Source.getRandom();
Source.updateRecentDisplayed(src);
return Source.getRecentDisplayed();
}
}
public void restartActivity(){
Intent myIntent = new Intent(this, TabbedActivity.class);
startActivity(myIntent);
finish();
}
}
IntentService
public class ArticleService extends IntentService {
public String responseStr = null;
public String urlStr = null;
public ArticleService() {
super("ArticleService");
}
#Override
protected void onHandleIntent(Intent intent) {
Uri url = intent.getData();
urlStr = url.toString();
responseStr = Asset.fetchSourceDataFromURL(urlStr);
sendBroadcast();
}
protected void sendBroadcast(){
Intent localIntent = new Intent(Asset.ARTICLE_BROADCAST_ACTION).putExtra(Asset.ARTICLE_EXTENDED_DATA_TYPE,responseStr);
if(urlStr.toLowerCase().contains(Asset.SORT_TOP_URL.toLowerCase())){
localIntent.putExtra(Asset.ARTICLE_EXTENDED_DATA_SORT,"TOP");
}else if (urlStr.toLowerCase().contains(Asset.SORT_LATEST_URL.toLowerCase())){
localIntent.putExtra(Asset.ARTICLE_EXTENDED_DATA_SORT,"LATEST");
}else if (urlStr.toLowerCase().contains(Asset.SORT_POPULAR_URL.toLowerCase())){
localIntent.putExtra(Asset.ARTICLE_EXTENDED_DATA_SORT,"POPULAR");
}
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
}
Error that I am not able to understand
01-26 07:57:29.789 1494-1494/in.co.yogender.newsnick.newsnick E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.co.yogender.newsnick.newsnick, PID: 1494
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.view.LayoutInflater.from(LayoutInflater.java:232)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:181)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:166)
at in.co.yogender.newsnick.newsnick.Adapters.ArticleAdapter.<init>(ArticleAdapter.java:0)
at in.co.yogender.newsnick.newsnick.TabbedActivity$PlaceholderFragment.update(TabbedActivity.java:197)
at in.co.yogender.newsnick.newsnick.TabbedActivity$ArticleStateReceiver.onReceive(TabbedActivity.java:273)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Thanks in advance
I think, you are updating GridView from IntentService where Context is null. Try to pull context from IntentService like below and let me know.
public void update(Context cont, ArrayList<Article> data){
mArticleAdapter = new ArticleAdapter(cont, R.layout.aricle_grid_element,data);
mGridView.setAdapter(mArticleAdapter);
}
My MainFragment is like
public class MainTabFragment extends Fragment {
public static int position_child_tab = 0, three_childs_tab_position = 0;
static int count = -1;
int position_tab = 0;
Bundle args;
public static MyTabLayout myTabLayout;
private static MainTabFragment sMainTabFragment;
public static NonSiwpablePager pager;
private Fragment mFragment;
public MainTabFragment() {
// Required empty public constructor
}
public static MainTabFragment getInstance() {
return sMainTabFragment;
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment MainTabFragment.
*/
// TODO: Rename and change types and number of parameters
public static MainTabFragment newInstance(String param1, String param2) {
return new MainTabFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
args = getArguments();
if (args != null && args.containsKey("pos_next"))
position_tab = args.getInt("pos_next");
if (args != null && args.containsKey("pos_end"))
position_child_tab = args.getInt("pos_end");
if (position_child_tab != 3) {
three_childs_tab_position = position_child_tab;
} else {
three_childs_tab_position = 0;
}
args = new Bundle();
args.putInt("pos_end", position_child_tab);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_tab_fragment, container, false);
myTabLayout = (MyTabLayout) view.findViewById(R.id.mainTabLayout);
pager = (NonSiwpablePager) view.findViewById(R.id.pager);
ViewPagerAdapter mAdapter = getViewPagerAdapter();
pager.setAdapter(mAdapter);
pager.setOffscreenPageLimit(4);
myTabLayout.setupWithViewPager(pager);
for (int i = 0; i < mAdapter.getCount(); i++) {
View customView = mAdapter.getCustomeView(getActivity(), i);
myTabLayout.getTabAt(i).setCustomView(customView);
}
pager.setCurrentItem(position_tab);
pager.setOffscreenPageLimit(3);
// changeTab();
myTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
Fragment fragment = getFragmentManager().findFragmentByTag("TOP");
if (fragment != null){
pager.setCurrentItem(position_tab);
}
Log.e("Fragment", fragment + "" +pager.getCurrentItem());
//
return view;
}
public void changeTab(){
pager.getCurrentItem();
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
myTabLayout.getTabAt(position_tab).getCustomView().setSelected(true);
}
public void setCurrentItem(int item) {
pager.setCurrentItem(item);
}
private ViewPagerAdapter getViewPagerAdapter() {
ViewPagerAdapter mAdapter = new ViewPagerAdapter(getChildFragmentManager());
String title_arr[] = {"ADVISORY", "TOP ADVISORS", "EXPERT VIEW"};
for (int i = 0; i < title_arr.length; i++) {
Map<String, Object> map = new Hashtable<>();
map.put(ViewPagerAdapter.KEY_TITLE, title_arr[i]);
if (i == 0) {
map.put(ViewPagerAdapter.KEY_FRAGMENT, AdvisoryPagerFragment.newInstance());
AdvisoryPagerFragment.newInstance().setTargetFragment(this, getTargetRequestCode());
} else if (i == 1) {
map.put(ViewPagerAdapter.KEY_FRAGMENT, TopAdvisoryPagerFragment.newInstance());
TopAdvisoryPagerFragment.newInstance().setTargetFragment(this, getTargetRequestCode());
} else if (i == 2) {
map.put(ViewPagerAdapter.KEY_FRAGMENT, ExperViewPagerFragment.newInstance());
ExperViewPagerFragment.newInstance().setTargetFragment(this, getTargetRequestCode());
}
mAdapter.addFragmentAndTitle(map);
}
return mAdapter;
}
public static class ViewPagerAdapter extends FragmentStatePagerAdapter {
private static final String KEY_TITLE = "fragment_title";
private static final String KEY_FRAGMENT = "fragment";
boolean abc = false;
private int[] drawables = new int[]{R.drawable.advisory_selector, R.drawable.top_advisors_selector, R.drawable.expertview_selector};
private List<Map<String, Object>> maps = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
public View getCustomeView(Context context, int pos) {
View mView = LayoutInflater.from(context).inflate(R.layout.custom_tab_view, null);
TextView mTextView = (TextView) mView.findViewById(R.id.textView);
mTextView.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/ufonts.com_cambria.ttf"));
ImageView mImageView = (ImageView) mView.findViewById(R.id.imageView2);
mImageView.setTag(pos);
/*if(count >0)
{
Toast.makeText(context,"Count Is "+count,Toast.LENGTH_SHORT).show();
mImageView = (ImageView) mImageView.getTag(0);
mImageView.setSelected(false);
}
*/
mImageView.setImageResource(drawables[pos]);
mTextView.setText(getPageTitle(pos));
return mView;
}
public void addFragmentAndTitle(Map<String, Object> map) {
maps.add(map);
}
#Override
public CharSequence getPageTitle(int position) {
return (CharSequence) maps.get(position).get(KEY_TITLE);
}
#Override
public Fragment getItem(int position) {
Log.e("Fragmentss" ,(Fragment) maps.get(position).get(KEY_FRAGMENT) +"");
return (Fragment) maps.get(position).get(KEY_FRAGMENT);
}
#Override
public int getCount() {
return maps.size();
}
}
}
Here I can get that this fragment is visible by using findFragmentByTag. I wanna know how I can use same thing for the child of this Fragment which are added using FragmentPagerAdapter.
Fragment fragment = getFragmentManager().findFragmentByTag("TOP");
if (fragment != null){
Log.e("Fragment", fragment + "" +pager.getCurrentItem()); }
So now I wanna do same thing and get name of current selected Fragment out of 3 which are mentioned above in FragmentPagerAdapter as AdvisoryPagerFragment,TopAdvisoryPagerFragment and ExperViewPagerFragment.
Try this
Fragment fragment = getFragmentManager().findFragmentByTag("TOP");
if(fragment instanceOf Fragment1){
// Do something
}else if(fragment instanceOf Fragment2){
// Do something
}else{
// Do something
}
I´ve got the following problem. After parsing a local xml file from the assets folder to a list I would like to send this parsed list to a fragment, which should show specific entries from this list in a listview.
Parsing works, the listview works, but I´m not sure, how to send lists via intent bundle extra to a fragment and how I can get this intent within the fragment.
At this example I would like to send the List<RowItem> pois to the static fragment class RouteItemFragment. The error is at
pois = getActivity().getIntent().getParcelableArrayListExtra("pois");
Message:
inferred type for type parameter T is not within its bound. should implement android.os.parcelable
Has anyone a hint for me?
public class RouteView extends ActionBarActivity implements ActionBar.TabListener {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*
*/
Integer citySave;
Integer routeSave;
String routeTitel;
private static int NUM_ITEMS = 2;
SectionsPagerAdapter mSectionsPagerAdapter;
ListView listView;
List<RowItem> pois;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_route_view);
Bundle b = getIntent().getExtras();
citySave = b.getInt("stadt");
routeSave = b.getInt("route");
routeTitel = b.getString("titel_route");
b.putString("titel_route",routeTitel);
b.putInt("route", routeSave);
RouteItemFragment fragobj = new RouteItemFragment();
fragobj.setArguments(b);
try {
PoiParser parser = new PoiParser();
pois = parser.parse(getAssets().open("poi_passau1.xml"));
b.putParcelableArrayList("pois", (java.util.ArrayList<? extends android.os.Parcelable>) pois);
} catch (IOException e) {
e.printStackTrace();
}
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.route_view, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
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:
return RouteItemFragment.newInstance(position);
case 1:
return MapFragment.newInstance(position);
default:
return PlaceholderFragment.newInstance(position);
}
}
#Override
public int getCount() {
// Show 2 total pages.
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
}
return null;
}
}
public static class RouteItemFragment extends ListFragment implements AdapterView.OnItemClickListener {
private static final String ARG_SECTION_NUMBER = "section_number";
ListView listView;
List<RowItem> pois;
public static RouteItemFragment newInstance(int sectionNumber) {
RouteItemFragment fragment = new RouteItemFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public RouteItemFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
pois = getActivity().getIntent().getParcelableArrayListExtra("pois");
CityListViewAdapter adapter = new CityListViewAdapter(getActivity(), R.layout.row_items, pois);
/**Collections.sort(pois, new Comparator<RowItem>() {
public int compare(RowItem s1, RowItem s2) {
return s1.getID().compareTo(s2.getID());
}
});*/
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_route_item, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.textRouteitem);
listView = (ListView) rootView.findViewById(android.R.id.list);
textView.setText(String.format(getResources().getString(R.string.routeViewfragment)) + " "
+ getActivity().getIntent().getStringExtra("titel_route"));
return rootView;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View parent, int position, long l) {
Intent intent = new Intent();
intent.setClass(getActivity(), PoiView.class);
RowItem pois = (RowItem) getListView().getItemAtPosition(position);
Bundle b = new Bundle();
//b.putInt("stadt", cities.getID());
b.putParcelableArrayList("titel_stadt", pois);
intent.putExtras(b);
startActivity(intent);
}
}
public static class MapFragment extends Fragment implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private static final String ARG_SECTION_NUMBER = "section_number";
private GoogleMap mMap;
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static MapFragment newInstance(int sectionNumber) {
MapFragment fragment = new MapFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
public MapFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
setUpMapIfNeeded();
return rootView;
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onDisconnected() {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
/**
* A placeholder fragment containing a simple view.
*/
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";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_route_view, container, false);
return rootView;
}
}
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent();
intent.setClass(RouteView.this, RouteChooseActivity.class);
Bundle b = new Bundle();
b.putInt("stadt", citySave);
intent.putExtras(b);
startActivity(intent);
finish();
}
public void onPause() {
super.onPause();
Bundle b = new Bundle();
b.putInt("stadt", citySave);
b.putInt("route", routeSave);
b.putString("route_titel",routeTitel);
finish();
}
public void onResume() {
super.onResume();
Bundle b = getIntent().getExtras();
citySave = b.getInt("stadt");
routeSave = b.getInt("route");
routeTitel = b.getString("route_titel");
}
public void onStop() {
super.onStop();
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_stadt:
setContentView(R.layout.activity_stadt);
Intent stadt = new Intent(RouteView.this, StadtActivity.class);
startActivity(stadt);
return true;
case R.id.action_route:
setContentView(R.layout.activity_route_choose);
Intent route = new Intent(RouteView.this, RouteChooseActivity.class);
startActivity(route);
return true;
case R.id.action_help:
setContentView(R.layout.activity_help);
Intent help = new Intent(RouteView.this, Help.class);
startActivity(help);
return true;
case R.id.action_exit:
moveTaskToBack(true);
System.exit(0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
PoiParser:
public class PoiParser {
List<RowItem> pois;
private RowItem poi;
private String text;
public PoiParser() {
pois = new ArrayList<RowItem>();
}
public List<RowItem> getPois() {
return pois;
}
public List<RowItem> parse(InputStream is) {
XmlPullParserFactory factory = null;
XmlPullParser parser = null;
try {
factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
parser = factory.newPullParser();
parser.setInput(is, null);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagname = parser.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equalsIgnoreCase("poi")) {
poi = new RowItem();
}
break;
case XmlPullParser.TEXT:
text = parser.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase("poi")) {
pois.add(poi);
} else if (tagname.equalsIgnoreCase("image")) {
poi.setImage(text);
} else if (tagname.equalsIgnoreCase("id")) {
poi.setID(Integer.parseInt(text));
} else if (tagname.equalsIgnoreCase("name")) {
poi.setTitle(text);
} else if (tagname.equalsIgnoreCase("desc")) {
poi.setDesc(text);
} else if (tagname.equalsIgnoreCase("imagedesc")) {
poi.setImageDesc(text);
} else if (tagname.equalsIgnoreCase("infotext")) {
poi.setInfoText(text);
} else if (tagname.equalsIgnoreCase("audio")) {
poi.setAudioPoi(text);
} else if (tagname.equalsIgnoreCase("latitude")) {
poi.setLatitudePoi(Double.parseDouble(text));
} else if (tagname.equalsIgnoreCase("longitude")) {
poi.setLongitudePoi(Double.parseDouble(text));
}
break;
default:
break;
}
eventType = parser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return pois;
}
}
RowItem
public class RowItem extends ArrayList<Parcelable> {
private String Bild;
private String Titel;
private String Desc;
private String imageDesc;
private String infoText;
private String audioPoi;
private int ID;
private double latitudePoi;
private double longitudePoi;
public RowItem() {
this.Bild = Bild;
this.Titel = Titel;
this.Desc = Desc;
this.imageDesc = imageDesc;
this.infoText = infoText;
this.audioPoi = audioPoi;
this.ID = ID;
this.latitudePoi = latitudePoi;
this.longitudePoi = longitudePoi;
}
public int getID() {return ID;}
public void setID(int ID) {this.ID = ID;}
public double getLatitudePoi() {return latitudePoi;}
public void setLatitudePoi(double latitudePoi) {this.latitudePoi = latitudePoi;}
public double getLongitudePoi() {return longitudePoi;}
public void setLongitudePoi(double longitudePoi) {this.longitudePoi = longitudePoi;}
public String getImage() {
return Bild;
}
public void setImage(String imageId) {
this.Bild = imageId;
}
public String getDesc() {
return Desc;
}
public void setDesc(String desc) {
this.Desc = desc;
}
public String getTitle() {
return Titel;
}
public void setTitle(String title) {
this.Titel = title;
}
public String getImageDesc() {return imageDesc;}
public void setImageDesc(String imageDesc){this.imageDesc = imageDesc;}
public String getInfoText() {return infoText;}
public void setInfoText(String infoText) {this.infoText = infoText;}
public String getAudioPoi() {return audioPoi;}
public void setAudioPoi(String audioPoi) {this.audioPoi = audioPoi;}
#Override
public String toString() {
return Titel + "\n" + Desc;
}
}
You should implement Parcelable interface for RowItem.
And also change your code
b.putParcelableArrayList("pois", pois);
public class RowItem implements Parcelable {
private String Bild;
private String Titel;
private String Desc;
private String imageDesc;
private String infoText;
private String audioPoi;
private int ID;
private double latitudePoi;
private double longitudePoi;
public RowItem() {
}
public RowItem(Parcel in) {
Bild = in.readString();
Titel = in.readString();
Desc = in.readString();
imageDesc = in.readString();
infoText = in.readString();
audioPoi = in.readString();
ID = in.readInt();
latitudePoi = in.readDouble();
longitudePoi = in.readDouble();
}
public int getID() {return ID;}
public void setID(int ID) {this.ID = ID;}
public double getLatitudePoi() {return latitudePoi;}
public void setLatitudePoi(double latitudePoi) {this.latitudePoi = latitudePoi;}
public double getLongitudePoi() {return longitudePoi;}
public void setLongitudePoi(double longitudePoi) {this.longitudePoi = longitudePoi;}
public String getImage() {
return Bild;
}
public void setImage(String imageId) {
this.Bild = imageId;
}
public String getDesc() {
return Desc;
}
public void setDesc(String desc) {
this.Desc = desc;
}
public String getTitle() {
return Titel;
}
public void setTitle(String title) {
this.Titel = title;
}
public String getImageDesc() {return imageDesc;}
public void setImageDesc(String imageDesc){this.imageDesc = imageDesc;}
public String getInfoText() {return infoText;}
public void setInfoText(String infoText) {this.infoText = infoText;}
public String getAudioPoi() {return audioPoi;}
public void setAudioPoi(String audioPoi) {this.audioPoi = audioPoi;}
#Override
public String toString() {
return Titel + "\n" + Desc;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(Bild);
dest.writeString(Titel);
dest.writeString(Desc);
dest.writeString(imageDesc);
dest.writeString(infoText);
dest.writeString(audioPoi);
dest.writeInt(ID);
dest.writeDouble(latitudePoi);
dest.writeDouble(longitudePoi);
}
#SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public RowItem createFromParcel(Parcel in) {
return new RowItem(in);
}
public RowItem[] newArray(int size) {
return new RowItem[size];
}
};
}
SCENARIO
I am creating a fragment structure with dynamic fragment creations. Each item in the fragment creates the next fragment. In the scenario I am storing all these fragments in the ArrayList of fragments so that I can easily replace the created fragment.
PROBLEM
Now I am replacing a fragment from the ArrayList by removing the fragment from a particular index and adding the new one. But when I try to get the fragment from that particular index it returns me the old data without calling the getItem function of the FragmentStateAdapter again.
Here is my Main class.
MainActivity.java
public class MainActivity extends FragmentActivity implements
onPageSelectedListener {
SectionsPagerAdapter mSectionsPagerAdapter;
static int current, listItem;
static String TAG = "MainActivity";
static ViewPager mViewPager;
static ArrayList<Fragment> FragmentList;
static ArrayList<String> titles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
public void init(){
FragmentList = new ArrayList<Fragment>();
titles = new ArrayList<String>();
mViewPager = (ViewPager) findViewById(R.id.pager);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public void addPage(int position, String title, String file, String tag) {
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putString(DummySectionFragment.ARG_FILE_NAME, file);
args.putString(DummySectionFragment.ARG_FILE_TAG, tag);
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
titles.add(position, title);
FragmentList.add(position, fragment);
}
public void NextScreen(int position, String title, String file, String tagname) {
if(FragmentList.size()>(position-1)){
for(int i=position; i<FragmentList.size(); i++){
FragmentList.remove(i);
}
}
addPage(position, title, file, tagname);
mViewPager.setCurrentItem(position);
}
public static class PageChanger extends
ViewPager.SimpleOnPageChangeListener {
private int currentPage;
#Override
public void onPageSelected(int position) {
currentPage = position;
}
public int getCurrentScreen() {
return currentPage;
}
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
addPage(0, "Main Fragment", "test.xml", "mytag");
}
#Override
public Fragment getItem(int position) {
return FragmentList.get(position);
}
#Override
public int getCount() {
return FragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) {
return "Main Categories";
}
getItem(position);
return titles.get(position);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
public static class DummySectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public static final String ARG_FILE_NAME = "file_name";
public static final String ARG_FILE_TAG = "tag_name";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
savedInstanceState = this.getArguments();
ListView parent_list = new ListView(getActivity());
String file_name = savedInstanceState.getString(ARG_FILE_NAME);
String tag_name = savedInstanceState.getString(ARG_FILE_TAG);
int current_level = savedInstanceState.getInt(ARG_SECTION_NUMBER);
PullParser pull = new PullParser(getActivity());
pull.pullXml(file_name, tag_name);
parent_list.setAdapter(new ListAdapter(getActivity(),
PullParser.Xml_Tag_Info, current_level));
return parent_list;
}
}
#Override
public void onPageSelected(int pageno) {
current = pageno;
}
}
I have found the answer just to reinstantiate the adapter after making the necessary changes. The edited code is here.
MainActivity.java
public class MainActivity extends FragmentActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
static int current, listItem;
static String TAG = "MainActivity";
static boolean flag = false;
/**
* The {#link ViewPager} that will host the section contents.
*/
static ViewPager mViewPager;
static ArrayList<DummySectionFragment> FragmentList;
static ArrayList<String> titles;
static FragmentManager fragManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
public void init() {
FragmentList = new ArrayList<DummySectionFragment>();
titles = new ArrayList<String>();
mViewPager = (ViewPager) findViewById(R.id.pager);
fragManager = getSupportFragmentManager();
mSectionsPagerAdapter = new SectionsPagerAdapter(fragManager);
mViewPager.setAdapter(mSectionsPagerAdapter);
titles.add(0, "Main Categories");
}
public void addPage(final int position, String file, String tag) {
DummySectionFragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putString(DummySectionFragment.ARG_FILE_NAME, file);
args.putString(DummySectionFragment.ARG_FILE_TAG, tag);
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
try {
FragmentList.set(position, fragment);
} catch (IndexOutOfBoundsException e) {
FragmentList.add(position, fragment);
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroyFragment(int position) {
SectionsPagerAdapter pagerAdapter = (SectionsPagerAdapter) mViewPager
.getAdapter();
pagerAdapter.destroyItem(mViewPager, position,
FragmentList.get(position));
pagerAdapter.notifyDataSetChanged();
}
public void addFragment(int position, Object object) {
SectionsPagerAdapter pagerAdapter = (SectionsPagerAdapter) mViewPager
.getAdapter();
pagerAdapter.notifyDataSetChanged();
}
public void NextScreen(int position, String title, String file,
String tagname) {
if (FragmentList.size() > position - 1) {
for (int i = FragmentList.size() - 1; i > position; i--) {
titles.remove(i);
FragmentList.remove(i);
}
titles.trimToSize();
FragmentList.trimToSize();
}
titles.add(position, title);
addPage(position, file, tagname);
mViewPager.setAdapter(new SectionsPagerAdapter(fragManager));
mViewPager.setCurrentItem(position);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
addPage(0, "catlist.xml", "pid-0");
}
#Override
public Fragment getItem(int position) {
return FragmentList.get(position);
}
public void setId() {
}
#Override
public int getCount() {
return FragmentList.size();
}
#Override
public int getItemPosition(Object object) {
return FragmentList.indexOf(object);
}
#Override
public CharSequence getPageTitle(int position) {
Log.v("titlePosition", position + "");
return titles.get(position);
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static ArrayList<Xml_Item_Data> resultList = new ArrayList<Xml_Item_Data>();
public static final String ARG_SECTION_NUMBER = "section_number";
public static final String ARG_FILE_NAME = "file_name";
public static final String ARG_FILE_TAG = "tag_name";
ListView parent_list;
public static Bundle setValues;
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
savedInstanceState = this.getArguments();
parent_list = new ListView(getActivity());
String file_name = savedInstanceState.getString(ARG_FILE_NAME);
String tag_name = savedInstanceState.getString(ARG_FILE_TAG);
int current_level = savedInstanceState.getInt(ARG_SECTION_NUMBER);
PullParser pull = new PullParser(getActivity());
pull.pullXml(file_name, tag_name);
ListAdapter list_Creator = new ListAdapter(getActivity(),
PullParser.Xml_Tag_Info, current_level);
parent_list.setAdapter(list_Creator);
return parent_list;
}
}
}
I think you can try return POSITION_NONE in your getItemPosition() method. Like here: How to force ViewPager to re-instantiate its items
I'm creating a demo app with the new android compatibility library. I want to show two listfragments with ViewPager. The first shows the root categories and the second shows the subcategories. After somebody clicks on root category the viewpager move to the subcategory, but it won't work, because always show the root category elements.
I spend few minutes with debug and I'm realised the ViewPager creates the second fragment after the first one.(I think the pager cache the next view or fragment.)
Is it possible to load the second fragment after onListItemClick?
Here is the code:
public class ViewPagerDemoActivity extends FragmentActivity implements OnBookSelectedListener {
private static int mSelectedCategoryId;
private MyAdapter mMyAdapter;
private ViewPager mPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupPager();
}
private void setupPager() {
mPager = (ViewPager) findViewById(R.id.pager);
mMyAdapter = new MyAdapter(getSupportFragmentManager());
mPager.setAdapter(mMyAdapter);
}
#Override
public void onBookSelected(int categoryId) {
mSelectedCategoryId = categoryId;
if (mSelectedCategoryId == 0) {
mPager.setCurrentItem(1);
} else {
mPager.setCurrentItem(0);
}
}
public static class MyAdapter extends FragmentPagerAdapter {
private static final int NUMBER_OF_FRAGMENTS = 2;
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return BookListFragment.newInstance(mSelectedCategoryId);
}
#Override
public int getCount() {
return NUMBER_OF_FRAGMENTS;
}
}
}
public class BookListFragment extends ListFragment {
private static final String ARGUMENT_KEY = "categoryId";
private OnBookSelectedListener mOnBookSelectedListener;
private int mCategoryId;
public static BookListFragment newInstance(int categoryId) {
BookListFragment bookListFragment = new BookListFragment();
Bundle argument = new Bundle();
argument.putInt(ARGUMENT_KEY, categoryId);
bookListFragment.setArguments(argument);
return bookListFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCategoryId = getArguments() != null ? getArguments().getInt(ARGUMENT_KEY) : 0;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Books.getBooks(mCategoryId)));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.pager_list, container, false);
View tv = v.findViewById(R.id.text);
((TextView) tv).setText("Category :" + mCategoryId);
return v;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if (mCategoryId == 0) {
mOnBookSelectedListener.onBookSelected(1);
} else {
mOnBookSelectedListener.onBookSelected(0);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOnBookSelectedListener = (OnBookSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + "Must Implement OnBookSelectedListener.");
}
}
public interface OnBookSelectedListener {
public void onBookSelected(int categoryId);
}
}
public class Books {
private static final String[] fruits = new String[] { "Apple", "Banana", "Orange" };
private static final String[] category = new String[] { "Lorem", "Dolor", "Ipsum" };
public static String[] getBooks(int categoryId) {
return categoryId == 0 ? category : fruits;
}
}
I solved the problem, I need to add List to the adapter and after that the getItem don't create new instance, only gets the item from the list.
This is the new code.
public class ViewPagerDemoActivity extends FragmentActivity implements OnBookSelectedListener {
private MyAdapter mMyAdapter;
private ViewPager mPager;
private BookOnPageChangeListener mBookOnPageChangeListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupPager();
}
private void setupPager() {
mPager = (ViewPager) findViewById(R.id.pager);
mMyAdapter = new MyAdapter(getSupportFragmentManager());
mPager.setAdapter(mMyAdapter);
mBookOnPageChangeListener = new BookOnPageChangeListener();
mPager.setOnPageChangeListener(mBookOnPageChangeListener);
}
#Override
public void onBookSelected(int categoryId) {
mMyAdapter.addPage(categoryId);
mPager.setCurrentItem(mBookOnPageChangeListener.getCurrentPage() + 1);
}
public static class MyAdapter extends FragmentPagerAdapter {
private List<Fragment> pages;
public MyAdapter(FragmentManager fm) {
super(fm);
initPages();
}
/**
* Create the list and add the first ListFragment to the ViewPager.
*/
private void initPages() {
pages = new ArrayList<Fragment>();
addPage(0);
}
/**
* Add new BookListFragment to the ViewPager.
*
* #param categoryId
* - the category id
*/
public void addPage(int categoryId) {
pages.add(BookListFragment.newInstance(categoryId));
}
#Override
public Fragment getItem(int position) {
return pages.get(position);
}
#Override
public int getCount() {
return pages.size();
}
}
/**
* Get the current view position from the ViewPager.
*/
public static class BookOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
private int currentPage;
#Override
public void onPageSelected(int position) {
// current page from the actual position
currentPage = position;
}
public int getCurrentPage() {
return currentPage;
}
}
}
Have you tried using setOnItemClickListener()?