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];
}
};
}
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);
}
I am using Glide library https://github.com/bumptech/glide (alternative of Picasso) and follow this tutorial http://blog.grafixartist.com/image-gallery-app-android-studio-1-4-glide/
Basic features work well such as show images as GridView, slide images use gesture in ViewPager. But I want to add more action like sharing and saving a current image in ViewPager, but I don't understand how to get curent position. I have tried adding Share function on activity like code below but nothing happen. I think I must put function on fragment. Maybe you can help me. Thanks.
public class DetailActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
public ArrayList<ImageModel> data = new ArrayList<>();
int pos;
Toolbar toolbar;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
data = getIntent().getParcelableArrayListExtra("data");
pos = getIntent().getIntExtra("pos", 0);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), data);
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setPageTransformer(true, new DepthPageTransformer());
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(pos);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_detail, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_share) {
share();
return true;
}
return super.onOptionsItemSelected(item);
}
private void share() { //Nothing happen
SubsamplingScaleImageView Imgv = (SubsamplingScaleImageView) mViewPager.findViewWithTag(mViewPager.getCurrentItem());
//Imgv.setBackgroundResource(data.get(pos).getUrl());
//Imgv.setTag(pos);
Imgv.setDrawingCacheEnabled(true);
Bitmap icon = Imgv.getDrawingCache();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
icon.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
try {
file.createNewFile();
FileOutputStream fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
String nama = getPackageName().toString();
String judul = getTitle().toString();
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");
Uri uri = Uri.parse("file:///sdcard/temporary_file.jpg");
shareIntent.putExtra(Intent.EXTRA_STREAM,uri);
String sAux = "I recommend " + (judul) + " for you:\n";
sAux = sAux + "https://play.google.com/store/apps/details?id="+(nama);
shareIntent.putExtra(Intent.EXTRA_TEXT, sAux);
startActivity(Intent.createChooser( shareIntent, "Share via"));
startActivity(shareIntent);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public ArrayList<ImageModel> data = new ArrayList<>();
public SectionsPagerAdapter(FragmentManager fm, ArrayList<ImageModel> data) {
super(fm);
this.data = data;
}
#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).
return PlaceholderFragment.newInstance(position, data.get(position).getName(), data.get(position).getUrl());
}
#Override
public int getCount() {
// Show 3 total pages.
return data.size();
}
#Override
public CharSequence getPageTitle(int position) {
return data.get(position).getName();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
String name, url;
int pos;
private static final String ARG_SECTION_NUMBER = "section_number";
private static final String ARG_IMG_TITLE = "image_title";
private static final String ARG_IMG_URL = "image_url";
#Override
public void setArguments(Bundle args) {
super.setArguments(args);
this.pos = args.getInt(ARG_SECTION_NUMBER);
this.name = args.getString(ARG_IMG_TITLE);
this.url = args.getString(ARG_IMG_URL);
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber, String name, String url) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putString(ARG_IMG_TITLE, name);
args.putString(ARG_IMG_URL, url);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public void onStart() {
super.onStart();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
final SubsamplingScaleImageView imageView = (SubsamplingScaleImageView) rootView.findViewById(R.id.detail_image);
final ImageView share = (ImageView) rootView.findViewById(R.id.share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //This is just test code
Toast.makeText(getContext(),
"Image + " + pos , // This pos is works great
Toast.LENGTH_LONG).show();
}
});
Glide
.with(getActivity())
.load(url)
.asBitmap()
.thumbnail(0.1f)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
imageView .setImage(ImageSource.bitmap(bitmap)
);
}
});
return rootView;
}
}
}
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'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.
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