App crashes after theme change (apparently caused by fragment) - java

My Main Activity has three tabs. Each tab is a fragment. Now if you change the theme (white and dark are available), the activity is being recreated so that the change takes effect. But the app crashes.
How I deal with the fragments:
if (savedInstanceState == null) {
pageadapter = new SectionsPageAdapter(getSupportFragmentManager());
rFragMore = new RoomlistFragmentMore();
rFragMyRooms = new RoomlistFragmentMyRooms();
rFragFavs = new RoomlistFragmentFavorites();
} else {
rFragMyRooms = (RoomlistFragmentMyRooms)pageadapter.getItem(0);
rFragFavs = (RoomlistFragmentFavorites)pageadapter.getItem(1);
rFragMore = (RoomlistFragmentMore)pageadapter.getItem(2);
pageadapter.clearAdapter();
pageadapter = new SectionsPageAdapter(getSupportFragmentManager());
}
How I set up the Adapter:
private void setupViewPager(ViewPager viewPager) {
pageadapter.addFragment(rFragMyRooms, getResources().getString(R.string.myrooms));
pageadapter.addFragment(rFragFavs, getResources().getString(R.string.favorites));
pageadapter.addFragment(rFragMore, getResources().getString(R.string.more));
viewPager.setAdapter(pageadapter);
}
My Adapter:
public class SectionsPageAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public void clearAdapter() {
mFragmentList.clear();
mFragmentTitleList.clear();
}
public SectionsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
}
And the Error Log:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileInputStream android.content.Context.openFileInput(java.lang.String)' on a null object reference
at com.yannick.mychatapp.RoomlistFragmentMore.readFromFile(RoomlistFragmentMore.java:246)
at com.yannick.mychatapp.RoomlistFragmentMore.addRoomToList(RoomlistFragmentMore.java:121)
at com.yannick.mychatapp.RoomlistFragmentMore.access$000(RoomlistFragmentMore.java:46)
at com.yannick.mychatapp.RoomlistFragmentMore$1.onDataChange(RoomlistFragmentMore.java:79)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##16.0.4:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##16.0.4:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##16.0.4:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
EDIT: the code of RoomlistFragmentMore
public class RoomlistFragmentMore extends Fragment {
private ListView listView;
private List<HashMap<String, String>> listItems = new ArrayList<>();
private String raumname, theme;
private static String userID = "";
private SimpleAdapter adapter;
private DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot().child("rooms");
private ArrayList<Room> raumliste = new ArrayList<>();
private TextView keinraumgefunden;
private String[] kat;
private static final String TAG = "RoomlistFragmentMore";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.roomlist_fragment_more,container,false);
listView = view.findViewById(R.id.listView);
keinraumgefunden = view.findViewById(R.id.keinraumgefunden);
kat = getResources().getStringArray(R.array.categories);
theme = readFromFile("mychatapp_theme.txt");
adapter = new SimpleAdapter(getActivity(), listItems, R.layout.listlayout,
new String[]{"name", "kat", "lock", "newest"},
new int[]{R.id.raumname, R.id.raumkat, R.id.raumlock, R.id.raumdatum});
listView.setAdapter(adapter);
root.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
addRoomToList(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getActivity(), R.string.nodatabaseconnection, Toast.LENGTH_SHORT).show();
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int position = listView.getPositionForView(view);
String roomname = listItems.get(position).values().toArray()[0].toString();
Room room = findRoom(raumliste, roomname);
request_password(room, position);
}
});
adapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
if (raumliste.isEmpty()) {
keinraumgefunden.setText(R.string.noroomfound);
} else {
keinraumgefunden.setText("");
}
}
});
return view;
}
private void addRoomToList(DataSnapshot dataSnapshot) {
HashMap<String, String> raeume = new HashMap<>();
raumliste.clear();
for(DataSnapshot uniqueKeySnapshot : dataSnapshot.getChildren()){
String name = uniqueKeySnapshot.getKey();
for(DataSnapshot roomSnapshot : uniqueKeySnapshot.getChildren()){
Room room = roomSnapshot.getValue(Room.class);
room.setRaumname(name);
if (!room.getPasswd().equals(readFromFile("mychatapp_raum_" + name + ".txt"))) {
raeume.put(name, kat[Integer.parseInt(room.getCaty())]+"/"+"\uD83D\uDD12"+"/");
raumliste.add(room);
}
break;
}
}
listItems.clear();
Iterator it = raeume.entrySet().iterator();
while (it.hasNext()){
HashMap<String, String> resultsMap = new HashMap<>();
Map.Entry pair = (Map.Entry)it.next();
resultsMap.put("name", pair.getKey().toString());
String daten = pair.getValue().toString();
String caty = daten.substring(0, daten.indexOf("/"));
String lock = daten.substring(daten.indexOf("/")+1, daten.lastIndexOf("/"));
String time = daten.substring(daten.lastIndexOf("/")+1, daten.length());
String newestTime = "";
int index = 0;
resultsMap.put("kat", caty);
resultsMap.put("lock", lock);
resultsMap.put("newest", newestTime);
if (time.equals("")) {
listItems.add(resultsMap);
} else {
listItems.add(index, resultsMap);
}
}
adapter.notifyDataSetChanged();
}
private void request_password(final Room room, final int position) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.enter_room, null);
raumname = room.getRaumname();
userID = readFromFile("mychatapp_userid.txt");
final EditText input_field = view.findViewById(R.id.room_password);
AlertDialog.Builder builder;
if (theme.equals(getResources().getStringArray(R.array.themes)[1])) {
builder = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.AlertDialogDark));
} else {
builder = new AlertDialog.Builder(getActivity());
}
builder.setTitle(R.string.pleaseenterpassword);
builder.setView(view);
builder.setCancelable(false);
builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
View view = ((AlertDialog) dialogInterface).getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
dialogInterface.cancel();
}
});
final AlertDialog alert = builder.create();
alert.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
Button b = alert.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (input_field.getText().toString().trim().equals(room.getPasswd())) {
Intent tabIntent = new Intent("tab");
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(tabIntent);
Intent intent = new Intent(getActivity(), ChatActivity.class);
intent.putExtra("room_name", room.getRaumname());
intent.putExtra("user_id",userID);
updateRoomList(position);
writeToFile(room.getPasswd(),"mychatapp_raum_" + raumname + ".txt");
alert.cancel();
startActivity(intent);
} else {
Toast.makeText(getActivity(), R.string.wrongpassword, Toast.LENGTH_SHORT).show();
}
}
});
}
});
alert.show();
}
public Room findRoom(ArrayList<Room> raumliste, String raumname) {
for (Room room : raumliste) {
if (room.getRaumname().equals(raumname)) {
return room;
}
}
return null;
}
public void writeToFile(String text, String datei) {
Context context = getActivity();
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(datei, Context.MODE_PRIVATE));
outputStreamWriter.write(text);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
public String readFromFile(String datei) {
Context context = getActivity();
String erg = "";
try {
InputStream inputStream = context.openFileInput(datei);
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
inputStream.close();
erg = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return erg;
}
private void updateRoomList(int position) {
listItems.remove(position);
adapter.notifyDataSetChanged();
}
}

The NullPointerException occured while onDataChange() was executed (you can see this by reading the stack trace). More specifically, readFromFile() needs a valid Context to open a file.
Since your app crashed we know that getActivity() did return null. How can this happen?
You add the ValueEventListener in onCreateView(). At this point in time, the Fragment has a valid Context (see the documentation for an explanation of the Lifecycle), so all is well for the moment.
But since you do not remove the ValueEventListener, it will continue to fire even if the Fragment is temporarily not attached to the Activity because the user swiped to the next page. The Fragment won't be garbage collected because you keep it in a list and reuse it.
This approach is basically ok if you implement null checks to avoid accessing the Activity, the Context or Views in general while they are not present. Of course, you could consider a stronger separation of the data and the View layer as suggested in this guide to app architecture

Related

how to save list view state and get back to that state

i am getting data from MySQL database in JSON form and showing in custom list view.list view is very lengthy. now i want that when i click on button in main activity it redirect me to the list view to the same position where i have left.
thanks in advance.
public class ShowParahDetail extends AppCompatActivity {
ProgressDialog pd;
CustomAdapter c;
ArrayList<Ayah_textAR> ar_ayahAR;
ArrayList<Ayah_textTR> ar_ayah_TR;
JazzyListView lv;
String intent_parah_ID;
String intent_parahName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_parah_detail);
intent_parah_ID=getIntent().getExtras().getString("parahID");
intent_parahName=getIntent().getExtras().getString("parahName");
setTitle(intent_parahName);
pd = new ProgressDialog(ShowParahDetail.this, R.style.pdtheme);
pd.setCancelable(false);
pd.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
pd.show();
lv= (JazzyListView) findViewById(R.id.lvparahDetail);
ar_ayahAR = new ArrayList<>();
ar_ayah_TR = new ArrayList<>();
ShowDataAR();
ShowTranslationUR();
}
private void ShowTranslationUR() {
new Thread(new Runnable() {
#Override
public void run() {
String RecievedString = "";
HashMap<String, String> params = new HashMap<String, String>();
params.put("parahid", intent_parah_ID);
Network network = new Network("showParahTranslationUR.php", params);
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
RecievedString = network.ToRecieveDataFromWeb();
JsonParsing jsonparsing = new JsonParsing(RecievedString);
ArrayList<HashMap<String, String>> convertedarraydata = jsonparsing.ParsejsonArray(RecievedString);
for (int i = 0; i < convertedarraydata.size(); i++) {
HashMap<String, String> positionHashmap;
positionHashmap = convertedarraydata.get(i);
String str_ayahText = positionHashmap.get("verseText");
String str_verseID = positionHashmap.get("verse_id");
String str_surahID = positionHashmap.get("surah_id");
Ayah_textTR ayahTR = new Ayah_textTR();
ayahTR.ayah_textTR = str_ayahText;
ayahTR.verse_id = str_verseID;
ayahTR.surah_id = str_surahID;
ar_ayah_TR.add(ayahTR);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void ShowDataAR() {
new Thread(new Runnable() {
#Override
public void run() {
String RecievedString = "";
HashMap<String, String> params = new HashMap<String, String>();
params.put("parahid", intent_parah_ID);
Network network = new Network("showParahDetails.php", params);
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
RecievedString = network.ToRecieveDataFromWeb();
JsonParsing jsonparsing = new JsonParsing(RecievedString);
ArrayList<HashMap<String, String>> convertedarraydata = jsonparsing.ParsejsonArray(RecievedString);
for (int i = 0; i < convertedarraydata.size(); i++) {
HashMap<String, String> positionHashmap;
positionHashmap = convertedarraydata.get(i);
String str_ayahID = positionHashmap.get("verse_id");
String str_ayahText = positionHashmap.get("verseText");
Ayah_textAR ayahText = new Ayah_textAR();
ayahText.ayah_id = str_ayahID;
ayahText.ayah_textAR = str_ayahText;
ar_ayahAR.add(ayahText);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ShowParahDetail.this == null)
return;
runOnUiThread(new Runnable() {
#Override
public void run() {
Parcelable state = lv.onSaveInstanceState();
lv.onRestoreInstanceState(state);
c = new CustomAdapter(ShowParahDetail.this, R.layout.cstm_parah, R.id.tv_parahNAME, ar_ayahAR);
lv.setAdapter(c);
if(pd!=null){
pd.dismiss();
pd = null;
}
}
});
}
}
}).start();
}
class CustomAdapter extends ArrayAdapter<Ayah_textAR> {
public CustomAdapter(Context context, int resource, int textViewResourceId, ArrayList<Ayah_textAR> objects) {
super(context, resource, textViewResourceId, objects);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.cstm_ayah, parent, false);
final TextView tv_ayah_text = (TextView) v.findViewById(R.id.tv_ayahText);
final TextView tv_ayahTR = (TextView) v.findViewById(R.id.tv_ayahTR);
try {
Ayah_textAR ayah = ar_ayahAR.get(position);
tv_ayah_text.setText(ayah.ayah_id + " : " + ayah.ayah_textAR);
Ayah_textTR parahTR = ar_ayah_TR.get(position);
tv_ayahTR.setText(parahTR.ayah_textTR);
}catch (Exception e){
notifyDataSetChanged();
}
});
return v;
}
}
public class Ayah_textAR {
String ayah_id;
String ayah_textAR;
}
public class Ayah_textTR {
String verse_id;
String ayah_textTR;
String surah_id;
}
#Override
public void onDestroy() {
super.onDestroy();
if (pd != null) {
pd.dismiss();
pd = null;
}
}
}
You have three activities, A,B and C. Start your activity B with Intent. And also start your activity C with intent. Then, if you start your activity A and wish to save data which are exist in C, then start your activity A with intent. And don't finish your activity C. And if you want to resume activity C, just call onBackPressed() from your activity A. Don't forget finishing your activity A. For this call onFinish().

Splash Screen using AsyncTask

I have a splash screen using AsyncTask, it will download some data from database and store the data in ArrayList. This ArrayList will be used for RecyclerView in fragments of MainActivity.class.
The problem is when I run the app from Android Studio to my phone, everything works perfectly. But, when I destroy the app and run it manually from my phone it will display blank white screen and then it will crash. And if I run once again after it crashed, the app will work. So, this app will always work only if I run it from Android Studio or after it crashed.
The error says that it is caused by the empty list. If I'm not mistaken, I think the AsyncTask doesn't seem to work properly after the activity is destroyed. But I don't know how to fix it. Please help me to solve this problem.
SplashScreen.java
public class SplashScreenActivity extends AppCompatActivity {
public static Event event;
private static List<Feed> feedList;
private static List<Event> eventList;
private static List<Event> todayList;
private static List<Event> upcomingList;
private static List<Partner> partnerList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splashscreen);
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
Config.TODAY_DATE = String.valueOf(today.monthDay) + "-" + String.valueOf(today.month) + "-" + String.valueOf(today.year);
new DownloadData().execute("");
}
class DownloadData extends AsyncTask<String, Integer, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
startActivity(new Intent(getBaseContext(), WelcomeActivity.class));
finish();
}
#Override
protected String doInBackground(String... params) {
RequestHandler rh = new RequestHandler();
String JSON_STRING = rh.sendGetRequest(Config.URL_GET_ALL_DATA);
JSONObject jsonObject;
eventList = new ArrayList<>();
todayList = new ArrayList<>();
upcomingList = new ArrayList<>();
partnerList = new ArrayList<>();
feedList = new ArrayList<>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray getEvent = jsonObject.getJSONArray(Config.TAG_JSON_EVENT);
for (int i = 0; i < getEvent.length(); i++) {
int id = getEvent.getJSONObject(i).getInt(Config.TAG_ID);
int eoId = getEvent.getJSONObject(i).getInt(Config.TAG_EO_ID);
String eoName = getEvent.getJSONObject(i).getString(Config.TAG_EO_NAME);
String title = getEvent.getJSONObject(i).getString(Config.TAG_TITLE);
String day = getEvent.getJSONObject(i).getString(Config.TAG_DAY);
String date = getEvent.getJSONObject(i).getString(Config.TAG_DATE);
int price = getEvent.getJSONObject(i).getInt(Config.TAG_PRICE);
event = new Event(id, eoId, eoName, title, day, date, price);
eventList.add(event);
if(Config.TODAY_DATE.equals(event.getDate())){
todayList.add(event);
} else {
upcomingList.add(event);
}
}
JSONArray getPartner = jsonObject.getJSONArray(Config.TAG_JSON_PARTNER);
for (int i = 0; i < getPartner.length(); i++) {
int pId = getPartner.getJSONObject(i).getInt(Config.TAG_ID);
String pName = getPartner.getJSONObject(i).getString(Config.TAG_NAME);
String pEmail = getPartner.getJSONObject(i).getString(Config.TAG_EMAIL);
String pPhone = getPartner.getJSONObject(i).getString(Config.TAG_PHONE);
String pPhoto = getPartner.getJSONObject(i).getString(Config.TAG_PHOTO_URL);
Partner partner = new Partner(pId, pName, pEmail, pPhone, pPhoto);
partnerList.add(partner);
}
JSONArray getArticle = jsonObject.getJSONArray(Config.TAG_JSON_ARTICLE);
for (int i = 0; i < getArticle.length(); i++) {
int feedId = getArticle.getJSONObject(i).getInt(Config.TAG_ID);
String feedAuthor = getArticle.getJSONObject(i).getString(Config.TAG_FEED_AUTHOR);
String feedTitle = getArticle.getJSONObject(i).getString(Config.TAG_FEED_TITLE);
String feedContent = getArticle.getJSONObject(i).getString(Config.TAG_FEED_CONTENT);
String feedDate = getArticle.getJSONObject(i).getString(Config.TAG_FEED_DATE);
String feedThumbnail = getArticle.getJSONObject(i).getString(Config.TAG_FEED_THUMBNAIL);
Feed feed = new Feed(feedId, feedAuthor, feedTitle, feedContent, feedDate, feedThumbnail);
feedList.add(feed);
}
} catch (JSONException e) {
e.printStackTrace();
}
return JSON_STRING;
}
}
public static List<Feed> getFeedList(){ return feedList;}
public static List<Event> getEventList() {return eventList;}
public static List<Event> getTodayList() { return todayList;}
public static List<Event> getUpcomingList() { return upcomingList;}
public static List<Partner> getPartnerList() {return partnerList;}
}
DiscoverFragment.java
public class DiscoverFragment extends Fragment implements ViewPager.OnPageChangeListener, View.OnClickListener {
protected View view;
private LinearLayout pager_indicator;
private int dotsCount;
private ImageView[] dots;
private List<Feed> feedList;
private List<Event> eventList;
private List<Partner> partnerList;
public DiscoverFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_discover, container, false);
RecyclerView recyclerViewEvent = (RecyclerView) view.findViewById(R.id.discover_event_recycler_view);
RecyclerView recyclerViewPartner = (RecyclerView) view.findViewById(R.id.discover_partner_recycler_view);
ClickableViewPager intro_images = (ClickableViewPager) view.findViewById(R.id.pager_introduction);
pager_indicator = (LinearLayout) view.findViewById(R.id.viewPagerCountDots);
eventList = SplashScreenActivity.getEventList();
partnerList = SplashScreenActivity.getPartnerList();
feedList = SplashScreenActivity.getFeedList();
EventAdapter eventAdapter = new EventAdapter(getContext(), eventList);
DiscoverPartnerAdapter discoverPartnerAdapter = new DiscoverPartnerAdapter(getContext(), partnerList);
DiscoverFeedAdapter mAdapter = new DiscoverFeedAdapter(getContext(), feedList);
final LinearLayoutManager layoutManagerEvent = new LinearLayoutManager(getContext());
final LinearLayoutManager layoutManagerPartner = new LinearLayoutManager(getContext());
layoutManagerEvent.setOrientation(LinearLayoutManager.HORIZONTAL);
layoutManagerPartner.setOrientation(LinearLayoutManager.HORIZONTAL);
addBottomDots(0);
intro_images.setAdapter(mAdapter);
intro_images.setCurrentItem(0);
intro_images.addOnPageChangeListener(this);
intro_images.setOnItemClickListener(new ClickableViewPager.OnItemClickListener() {
#Override
public void onItemClick(int position) {
Config.FEED_ID = position;
startActivity(new Intent(getContext(), ArticleActivity.class));
}
});
return view;
}
private void addBottomDots(int currentPage) {
dots = new ImageView[feedList.size()]; //the problem
pager_indicator.removeAllViews();
for (int i = 0; i < dots.length; i++) {
dots[i] = new ImageView(getContext());
dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
params.setMargins(4, 0, 4, 0);
pager_indicator.addView(dots[i], params);
}
if (dots.length > 0)
dots[currentPage].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));
}
#Override
public void onClick(View v) {
switch (v.getId()) {
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
addBottomDots(position);
for (int i = 0; i < dotsCount; i++) {
dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));
}
dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));
}
}
LogCat
01-29 00:40:57.565 32535-32535/com.irmaelita.esodiaapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.irmaelita.esodiaapp, PID: 32535
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at com.irmaelita.esodiaapp.fragment.DiscoverFragment.addBottomDots(DiscoverFragment.java:181)
at com.irmaelita.esodiaapp.fragment.DiscoverFragment.onCreateView(DiscoverFragment.java:158)
feedList is null. You create feedList instance when DownloadData task is executed. But you call feedList.size() in addBottomDots when fragment view should be created. So, most probably addBottomDots is called before DownloadData task is executed. You need to fix it.
The feedlist in your discover fragment is going empty while initializing. Please set a null check before doing so.It not about running from android studio.If I have understood it correctly you are trying to access a list from splasScreen activity after finishing it. ie in post execute you finish the current activity and the fragment is in main activity,so the list is going null.So if this is the case (and please correct me if not) then either download the data somewhere centrally or best way send it to main activity with intent and use it there. Also when running from android studio kill the app manually and run it again,while the phone is connected and see if it crashes in current scenario.
Send your data from doInBackground to MainActivity with sendBroadcast
Add broadcast method in DownloadData class
private void broadcast(SplashParcel parcel) {
Intent i = new Intent("splash_parcel");
i.putExtra("values", parcel);
sendBroadcast(i);
}
#Override
protected String doInBackground(String... params) {
// your code
// ..
try {
// your code
// ..
// send splashParcel to MainActivity
SplashParcel splashParcel = new SplashParcel(feedList, eventList, todayList, upcomingList, partnerList);
broadcast (splashParcel);
} catch (JSONException e) {
e.printStackTrace();
}
return JSON_STRING;
}
Add new class SplashParcel.java
public class SplashParcel implements Parcelable {
public static final Creator<SplashParcel> CREATOR = new Creator<SplashParcel>() {
#Override
public SplashParcel createFromParcel(Parcel in) {
return new SplashParcel(in);
}
#Override
public SplashParcel[] newArray(int size) {
return new SplashParcel[size];
}
};
private static List<Feed> _feedList;
private static List<Event> _eventList;
private static List<Event> _todayList;
private static List<Event> _upcomingList;
private static List<Partner> _partnerList;
protected SplashParcel(Parcel in) {
_feedList = new ArrayList<Feed>();
in.readList(_feedList, null);
_eventList = new ArrayList<Event>();
in.readList(_eventList, null);
_todayList = new ArrayList<Event>();
in.readList(_todayList, null);
_upcomingList = new ArrayList<Event>();
in.readList(_upcomingList, null);
_partnerList = new ArrayList<Partner>();
in.readList(_partnerList, null);
}
public SplashParcel(List<Feed> feedList, List<Event> eventList, List<Event> todayList, List<Event> upcomingList, List<Partner> partnerList) {
_feedList = feedList;
_eventList = eventList;
_todayList = todayList;
_upcomingList = upcomingList;
_partnerList = partnerList;
}
public SplashParcel() {
}
public List<Feed> getFeedList() {
return _feedList;
}
public void setFeedList(List<Feed> feedList) {
_feedList = feedList;
}
public List<Event> getEventList() {
return _eventList;
}
public void setEventList(List<Event> eventList) {
_eventList = eventList;
}
public List<Event> getTodayList() {
return _todayList;
}
public void setTodayList(List<Event> todayList) {
_todayList = todayList;
}
public List<Event> getUpcomingList() {
return _upcomingList;
}
public void setUpcomingList(List<Event> upcomingList) {
_upcomingList = upcomingList;
}
public List<Partner> getPartnerList() {
return _partnerList;
}
public void setPartnerList(List<Partner> partnerList) {
_partnerList = partnerList;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeList(_feedList);
parcel.writeList(_eventList);
parcel.writeList(_todayList);
parcel.writeList(_upcomingList);
parcel.writeList(_partnerList);
}
}
MainActivity.java
// member variable
private BroadcastReceiver _splashReceiver;
private Bundle _bundle = new Bundle();
#Override
protected void onResume() {
super.onResume();
splashReceiver();
}
// receive splashParcel from SplashScreenActivity
private void splashReceiver() {
if (_splashReceiver == null) {
_splashReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
SplashParcel splashParcel = intent.getParcelableExtra("values");
if (splashParcel != null) {
// save splashParcel into _budle
_bundle.putParcelable("splash_parcel", splashParcel);
}
}
};
registerReceiver(_splashReceiver, new IntentFilter("splash_parcel"));
}
}
//Send _bundle to DiscoverFragment
private void showDiscoverFragment(){
if(_bundle != null) {
// create instance of discoverFragment with passing _bundle as arguments
DiscoverFragment discoverFragment = new DiscoverFragment();
discoverFragment.setArguments(_bundle);
// replace activity_main.xml with discoverFragment
getSupportFragmentManager().beginTransaction().replace(R.id.main_container, discoverFragment).addBackStack(null).commit();
}
}
In onCreateView of DiscoverFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
SplashParcel splashParcel = getArguments().getParcelable("splash_parcel");
if(splashParcel != null) {
// your splashParcel ready in here
List<Feed> feedList = splashParcel.getFeedList()
List<Event> eventList = splashParcel.getEventList()
List<Event> todayList = splashParcel.getTodayList();
List<Event> upcommingList = splashParcel.getUpcomingList();
List<Partner> partnerList = splashParcel.getPartnerList();
}
}

Values duplicating when fetching data from database and displaying to ListView

Im new to Android Developement and currently working on an app that should give me the time between first time clicking a button and second time clicking the button and add it to a currently selected customer.
Current Status of App:
I established a connection to da mySql Database using Volley and a local webservice.
It works to insert my customers and time stamps to the table, but when loading times for a specific customer i get a strange result in one case. I tried debugging it but the app keeps crashing on debugging without a message. When not debugging it doesnt crash but shows weird data.
To the problem:
In my main activity called "ZeitErfassen" i have a button to get an overview of all customers display in a ListView.
I create the Listview with a custom ArrayAdapter because i want to pass my objects to the next Activity where my customers are displayed.
So onCreate of the overview of customers i create a new arraylist and fill it with all customers from my database. this list i pass to my customadapter and then set it as my adapter of the Listview.
Now, when i click on an item, i call a php script and pass the customer_id to the query to fetch all times from database where customer_id = customer_id.
Now the part where i get "strange" data...
1.(Source:ZeitErfassen;Destination:AddCustomer) I create a new customer,example xyz, in the app, data gets passed to the database.
2.(Source:ZeitErfassen;Destination:DisplayCustomer) I call my overview for all customers where the ListView is filled with data as described above. At the end ob the List I see the customer i just created,xyz.
3.Go back to Main Activity(ZeitErfassen)
4.(Source:ZeitErfassen;Destination:DisplayCustomer)I open the overview for all customers again, and it shows my last created user two times! so last entry, xyz, entry before last, xyz!
After that, i can open the view as many times as i want, the customer never gets duplicated again!
The debugger stopps after step 2.
Now when i click on the new customers, it calls the script to fetch the times by customer_id.
One of the xyz entrys display the correct times from database.
The second one, i just found out, display the times where customer_id="". In the database the value for "" is 0.
I have no clue where the second customer suddenly appears from and debugging didnt help me either -.-
When i close the app an open it again, there ist just one entry for the user that was visible twice before closing the app. It doesnt duplicate on opening view...
Here is my code..
Main Activity ZeitErfassen
public class ZeitErfassen extends AppCompatActivity {
public static LinkedList<Kunde> kunden = new LinkedList<Kunde>();
boolean running = false;
long startTime,endTime,totalTime;
private SharedPreferences app_preferences;
private SharedPreferences.Editor editor;
private TextView displayTime;
public Button startEndButton;
private ArrayAdapter<String> adapter;
private Spinner spinner;
public static Kunde selectedCustomer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zeit_erfassen);
//Einstellungen laden
app_preferences = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
startTime= app_preferences.getLong("startTime", 0);
endTime = app_preferences.getLong("endTime", 0);
running = app_preferences.getBoolean("running", false);
displayTime = (TextView)findViewById(R.id.zeit_bei_Kunde);
displayTime.setText((CharSequence) app_preferences.getString("zeitAnzeige", "Zeit bei Kunde"));
startEndButton = (Button)findViewById(R.id.start_Timer);
startEndButton.setText((CharSequence) app_preferences.getString("timerButton", "Start Timer"));
DatabaseHelper.customerFromDatabaseToList(this);
editor = app_preferences.edit();
editor.commit();
}
public void onDestroy() {
super.onDestroy();
editor.putLong("startTime", startTime);
editor.putString("zeitAnzeige", (String) displayTime.getText());
editor.putString("timerButton", (String) startEndButton.getText());
editor.putLong("endTime", endTime);
editor.putLong("totalTime", totalTime);
editor.putBoolean("running", app_preferences.getBoolean("running", false));
editor.commit();
this.finish();
}
public void onResume() {
super.onResume();
// saveCustomers();
// createDropDown();
}
public void startTimer(View view) {
editor = app_preferences.edit();
if(running == false) {
startTime = getTime();
running = true;
editor.putLong("startTime", startTime);
startEndButton.setText("End Timer");
displayTime.setText("Zeitstoppung läuft");
editor.putString("zeitAnzeige", (String) displayTime.getText());
editor.putString("timerButton", (String) startEndButton.getText());
editor.putBoolean("running", true);
editor.commit();
} else {
setSelectedCustomer();
endTime = getTime();
editor.putLong("endTime",endTime);
totalTime = endTime - startTime;
editor.putLong("totalTime", totalTime);
displayTime.setText(formatTime(totalTime));
editor.putString("zeitAnzeige", (String) displayTime.getText());
startEndButton.setText("Start Timer");
editor.putString("timerButton", (String) startEndButton.getText());
running = false;
editor.putBoolean("running", false);
editor.commit();
DatabaseHelper.timeToDatabase(String.valueOf(selectedCustomer.getId()),formatTime(totalTime),this);
// selectedCustomer.saveTimeToCustomer(selectedCustomer, formatTimeForCustomer(totalTime));
}
}
public String formatTime(Long totalTime) {
int hours = (int) ((totalTime / (1000*60*60)) % 24);
int minutes = (int) ((totalTime / (1000*60)) % 60);
int seconds = (int) (totalTime / 1000) % 60;
String time = (String.valueOf(hours) + ":" + String.valueOf(minutes) + ":" + String.valueOf(seconds));
return time;
}
public String formatTimeForCustomer(Long totalTime) {
StringBuilder time = new StringBuilder();
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
time.append((String.valueOf(year) + "." + String.valueOf(month) + "." + String.valueOf(day))).append(formatTime(totalTime));
return time.toString();
}
public void neuerKunde(View view) {
Intent intent = new Intent(this, AddKunde.class);
startActivity(intent);
}
public void kundenÜbersicht(View view) {
// setSelectedCustomer();
Intent intent = new Intent(this, DisplayCustomer.class);
startActivity(intent);
}
public long getTime() {
long millis = System.currentTimeMillis();
return millis;
}
public void setSelectedCustomer() {
if(kunden.size() > 0) {
if (spinner.getSelectedItem().toString() != null) {
String tempCustomer = spinner.getSelectedItem().toString();
for (Kunde k : kunden) {
if (k.getName().equals(tempCustomer)) {
selectedCustomer = k;
}
}
}
}
}
public void createDropDown() {
/*File file = new File(this.getFilesDir(),"kunden.ser"); NOT USED BECAUSE DATABASE WORKS
if(file.exists()) {
Kunde.importFromFile(this);
}*/
if (kunden.size() > 0) {
spinner = (Spinner) findViewById(R.id.chooseCustomer);
// Create an ArrayAdapter using the string array and a default spinner layout
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, DisplayCustomer.namesOfCustomers());
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
}
}
}
DisplayCustomer(Where all customers are displayed with data from Database)
public class DisplayCustomer extends AppCompatActivity {
CustomerAdapter customerAdapter;
public ArrayAdapter<String> adapterCustomerView;
private ListView listCustomerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_customer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ArrayList<Kunde> customerList = getCustomerObjects();
customerAdapter = new CustomerAdapter(this,customerList);
listCustomerView = (ListView)findViewById(R.id.list_View_Customers);
// adapterCustomerView = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, namesOfCustomers());
listCustomerView.setAdapter(customerAdapter);
openCustomerDetails();
}
public static ArrayList<String> namesOfCustomers() {
ArrayList<String> customerNames = new ArrayList<>();
if(ZeitErfassen.kunden.size() > 0 ) {
for (Kunde k : ZeitErfassen.kunden) {
customerNames.add(k.getName());
}
}
return customerNames;
}
public static ArrayList<Kunde> getCustomerObjects() {
ArrayList<Kunde> customerList = new ArrayList<>();
if(ZeitErfassen.kunden.size() > 0 ) {
for (Kunde k : ZeitErfassen.kunden) {
customerList.add(k);
}
}
return customerList;
}
public void openCustomerDetails() {
listCustomerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Kunde kunde = new Kunde();
kunde = (Kunde)listCustomerView.getItemAtPosition(position);
Intent intent = new Intent(DisplayCustomer.this, DisplayDetailedCustomer.class);
intent.putExtra("selectedCustomerObject",(Parcelable)kunde);
startActivity(intent);
}
});
}
}
My CustomerAdapter to pass data from one intent to another.
public class CustomerAdapter extends ArrayAdapter<Kunde> {
public CustomerAdapter(Context context, ArrayList<Kunde> customerList) {
super(context,0,customerList);
}
public View getView(int position, View convertView, ViewGroup parent) {
//Data for this position
Kunde kunde = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.items_customer_layout, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvCustomerName);
// Populate the data into the template view using the data object
tvName.setText(kunde.getName());
// Return the completed view to render on screen
return convertView;
}
}
DatabaseHelper Class
public class DatabaseHelper {
public static RequestQueue requestQueue;
public static String host = "http://192.168.150.238/";
public static final String insertUrl = host+"insertCustomer.php";
public static final String showUrl = host+"showCustomer.php";
public static final String insertTimeUrl = host+"insertTime.php";
public static final String showTimeUrl = host+"showTimes.php";
public static void customerFromDatabaseToList(final Context context) {
//Display customer from database
requestQueue = Volley.newRequestQueue(context);
final ArrayList<String> customerNames = new ArrayList<>();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, showUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray customers = response.getJSONArray("customers");
if(customers.length() > 0) {
for (int i = 0; i < customers.length(); i++) {
JSONObject customer = customers.getJSONObject(i);
String customerName = customer.getString("cus_name");
String customerAddress = customer.getString("cus_address");
int customerID = Integer.valueOf(customer.getString("cus_id"));
if (customerName != null && customerAddress != null) {
try {
Kunde k = new Kunde(customerName, customerAddress, customerID);
if (!listContainsObject(k)) {
ZeitErfassen.kunden.add(k);
}
} catch (Exception e) {
showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
}
} else {
showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
requestQueue.add(jsonObjectRequest);
}
public static boolean listContainsObject(Kunde cust) {
for(Kunde k : ZeitErfassen.kunden) {
if(k.getId() == cust.getId()) {
return true;
}
}
return false;
}
public static void timeToDatabase(final String customer_id, final String time_value, final Context context) {
requestQueue = Volley.newRequestQueue(context);
StringRequest request = new StringRequest(Request.Method.POST, DatabaseHelper.insertTimeUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
showAlert("Fehler","Fehler bei Verbindung zur Datenbank",context);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("customerid",customer_id);
parameters.put("timevalue",time_value);
return parameters;
}
};
requestQueue.add(request);
};
public static void showAlert(String title, String message, Context context) {
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage(message)
.setTitle(title);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
}
public static ArrayList<String> timesFromDataBaseToList(final Context context,final int customer_id) {
requestQueue = Volley.newRequestQueue(context);
final String cus_id = String.valueOf(customer_id) ;
final ArrayList<String> customerTimes = new ArrayList<>();
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, showTimeUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object = new JSONObject(response.toString());
JSONArray times = object.getJSONArray("customertimes");
if (times.length() > 0) {
for (int i = 0; i < times.length(); i++) {
JSONObject jsonObject = times.getJSONObject(i);
String timeValue = jsonObject.getString("time_value");
if (timeValue != null) {
customerTimes.add(timeValue);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context,"Fehler beim Holen der Zeiten",Toast.LENGTH_LONG).show();
error.printStackTrace();
}
}){
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("cus_id",cus_id);
return parameters;
}
};
requestQueue.add(jsonObjectRequest);
return customerTimes;
};
}
DisplayDetailedCustomer / Display the times
public class DisplayDetailedCustomer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_detailed_customer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent getCustomerParcable = getIntent();
Kunde customer = getCustomerParcable.getExtras().getParcelable("selectedCustomerObject");
TextView displayCustomerNameDetailed =(TextView) findViewById(R.id.detailedCustomerViewName);
TextView displayCustomerAddressDetailed =(TextView) findViewById(R.id.detailedCustomerAddress);
ListView timeListView = (ListView)findViewById(R.id.detailedTimeListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, DatabaseHelper.timesFromDataBaseToList(this,customer.getId()));
timeListView.setAdapter(adapter);
displayCustomerNameDetailed.setText(customer.getName());
displayCustomerAddressDetailed.setText(customer.getAdresse());
}
}
Kunde Class / Customer Class with interface Parcelable
public class Kunde implements Serializable,Parcelable {
private String name;
private String adresse;
private int id;
public LinkedList<String> zeiten;
public Kunde(String name, String adresse) throws Exception{
setName(name);
setAdresse(adresse);
zeiten = new LinkedList<String>();
}
public Kunde(String name, String adresse,int id) throws Exception{
setName(name);
setAdresse(adresse);
setId(id);
zeiten = new LinkedList<String>();
}
public Kunde(){};
public void setId(int id) {
this.id = id;
}
public int getId(){
return id;
}
public void setName(String name) throws Exception {
if(name != null) {
this.name = name;
} else throw new Exception("Name ist ungueltig! in setName");
}
public void setAdresse(String adresse) throws Exception{
if(adresse != null) {
this.adresse = adresse;
}else throw new Exception("Adresse ist ungueltig! in setAdresse");
}
public String getName() {
return name;
}
public String getAdresse() {
return adresse;
}
public void saveZeit(Long totalTime) {
zeiten.add(String.valueOf(totalTime));
}
public void saveTimeToCustomer(Kunde customer,String time){
customer.zeiten.add(time);
}
//------------------------------------Parcelable Methods to pass Daata from one Intent to another----------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.name);
dest.writeString(this.adresse);
// dest.writeList(this.zeiten);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<Kunde> CREATOR = new Parcelable.Creator<Kunde>() {
public Kunde createFromParcel(Parcel in) {
return new Kunde(in);
}
public Kunde[] newArray(int size) {
return new Kunde[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private Kunde(Parcel in) {
LinkedList<String> zeiten = null;
id = in.readInt();
name = in.readString();
adresse = in.readString();
}
}
Thanks for taking your time!!

java.lang.IllegalStateException:The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged

I have a sliding image that extends pageradapter. At first it was working. But when i open new activity then press the back button the app is crashing and i've got this error :
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 10, found: 0 Pager id: malate.denise.chelsie.igphthesisbfinal:id/pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class malate.denise.chelsie.igphthesisbfinal.SlidingImage_Adapter
Here's my SlidingImage_Adapter.class
public class SlidingImage_Adapter extends PagerAdapter {
private ArrayList<Pictures> IMAGES;
private LayoutInflater inflater;
private Context context;
public SlidingImage_Adapter(Context context,ArrayList<Pictures> IMAGES) {
this.context = context;
this.IMAGES=IMAGES;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return IMAGES.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.slidingimage_layout, view, false);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout
.findViewById(R.id.image);
new DownloadImageTask(imageView).execute(IMAGES.get(position).getPhotopath());
// imageView.setImageResource(IMAGES.get(position));
view.addView(imageLayout, 0);
return imageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
notifyDataSetChanged();
}
#Override
public Parcelable saveState() {
return null;
}
and my AttractionInfo.class
public class AttractionInfo extends ActionBarActivity implements View.OnClickListener {
TextToSpeech tts;
TextView nameofplace,location,exact_address,operatinghours,info;
String nameofplace_s,location_s,exact_address_s,operatinghours_s,info_s,latlang_s,path_s,category_s;
ImageView play,rate,addtoplan,map;
ArrayList<Pictures> records;
private static ViewPager mPager;
private static int currentPage = 0;
String line=null;
private static int NUM_PAGES = 0;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_attraction_info);
map = (ImageView)findViewById(R.id.map);
map.setOnClickListener(this);
records=new ArrayList<Pictures>();
nameofplace = (TextView) findViewById(R.id.nameofplace);
info = (TextView) findViewById(R.id.info);
exact_address = (TextView) findViewById(R.id.exact_address);
location = (TextView)findViewById(R.id.location);
operatinghours=(TextView)findViewById(R.id.operatinghours);
play = (ImageView) findViewById(R.id.play);
rate = (ImageView) findViewById(R.id.rate);
addtoplan = (ImageView)findViewById(R.id.addtoplan);
addtoplan.setOnClickListener(this);
Bundle extras = getIntent().getExtras();
play.setOnClickListener(this);
rate.setOnClickListener(this);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
getSupportActionBar().setDisplayShowTitleEnabled(false);
tts = new TextToSpeech(AttractionInfo.this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR){
tts.setLanguage(Locale.ENGLISH);
}
}
});
if (extras != null) {
nameofplace_s = extras.getString("name");
nameofplace.setText(nameofplace_s);
info_s = extras.getString("description");
info.setText(info_s);
exact_address_s = extras.getString("exactaddress");
exact_address.setText(exact_address_s);
location_s = extras.getString("location");
location.setText(location_s);
operatinghours_s=extras.getString("operatinghours");
operatinghours.setText(operatinghours_s);
latlang_s = extras.getString("latlang");
path_s=extras.getString("path");
category_s = extras.getString("category");
}
}
public void onStart() {
super.onStart();
fetchphoto bt = new fetchphoto();
bt.execute();
}
#Override
protected void onPause() {
if (tts != null){
tts.stop();
tts.shutdown();
}
super.onPause();
}
#Override
public void onClick(View v) {
if (v == play) {
String speech1 = nameofplace.getText().toString();
String speech2 = info.getText().toString();
String speech = speech1 + "." + speech2;
tts.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
} else if (v==rate){
Intent myIntent = new Intent(this, ListOfReviews.class);
myIntent.putExtra("placename", nameofplace_s);
myIntent.putExtra("category",category_s);
startActivity(myIntent);
}else if(v==addtoplan){
Intent myIntent = new Intent(this, AddPlan.class);
myIntent.putExtra("placename", nameofplace_s);
myIntent.putExtra("category",category_s);
startActivity(myIntent);
}else if (v == map){
Intent myIntent = new Intent(this, Map.class);
myIntent.putExtra("placename", nameofplace_s);
myIntent.putExtra("category",category_s);
myIntent.putExtra("latlang",latlang_s);
myIntent.putExtra("address",exact_address_s);
myIntent.putExtra("path",path_s);
startActivity(myIntent);
}
}
private void init() {
SlidingImage_Adapter adapter = new SlidingImage_Adapter(this,records);
for(int i=0;i<records.size();i++){
Pictures pics = records.get(i);
String pic = pics.getPhotopath();
adapter.notifyDataSetChanged();
}
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(adapter);
CirclePageIndicator indicator = (CirclePageIndicator)
findViewById(R.id.indicator);
indicator.setViewPager(mPager);
final float density = getResources().getDisplayMetrics().density;
indicator.setRadius(5 * density);
NUM_PAGES =records.size();
// Auto start of viewpager
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == NUM_PAGES) {
currentPage = 0;
}
mPager.setCurrentItem(currentPage++, true);
}
};
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
},5000, 5000);
// Pager listener over indicator
indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
currentPage = position;
}
#Override
public void onPageScrolled(int pos, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int pos) {
}
});
}
private class fetchphoto extends AsyncTask<Void, Void, Void> {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(Void... params) {
InputStream is = null;
String result = "";
nameValuePairs.add(new BasicNameValuePair("cityname", nameofplace_s));
try
{
records.clear();
HttpParams httpParams = new BasicHttpParams();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://igph.esy.es/getphoto.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Log.e("pass 1", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 1", e.toString());
}
try
{
BufferedReader reader = new BufferedReader
(new InputStreamReader(is,"utf-8"),8);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.e("pass 2", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 2", e.toString());
}
//parse json data
try {
Log.i("tagconvertstr", "["+result+"]");
// Remove unexpected characters that might be added to beginning of the string
result = result.substring(result.indexOf(""));
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
Pictures p = new Pictures();
p.setPhotoname(json_data.getString("photo_name"));
p.setPlacename(json_data.getString("place_name"));
p.setCategory(json_data.getString("category"));
p.setPhotopath(json_data.getString("path"));
records.add(p);
}
} catch (Exception e) {
Log.e("ERROR", "Error pasting data " + e.toString());
}
return null;
}
protected void onPostExecute(Void result) {
// if (pd != null) pd.dismiss(); //close dialog
Log.e("size", records.size() + "");
init();
}
}
}
I've red some similar problems and learned that adding notifychanged may solved the problem but i dont where to place it. Hope you can help m . thanks

FragmentPagerAdapter dynamic tabs and page count

My application pulls data from a web service that generates different sections for each user. Then I am going to use these sections to create tabs using FragmentPagerAdapter.
I have used an Async task to pull data from the web service. However the overridden methods such as getCount() and getPageTitle() in the FragmentPagerAdapter executed prior to my asynctask and completes its job. How can I prevent this and generate dynamic number of tabs and their title name based on the data fetched from the web service?
In other words how can I create dynamic number of tabs and titles based on the data fetch from the web service
My Code for FragmentPagerAdapter as below. As you can see I have hard coded the amount of tabs as well as their title names.
public class SectionsPagerAdapter extends FragmentPagerAdapter{
private boolean proceedStatus = false;
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx";
//list of fragments need to be added dynamically
public final ArrayList<Fragment> screens = new ArrayList<Fragment>();
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 DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new SectionFragment();
Bundle args = new Bundle();
args.putInt(SectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Camera".toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return "SECTION 4";
}
return null;
}
//setting the section title
private void setSectionTitle(){
}
//count the number of sections
private int countNumberofSections(){
int numberOfSection = 0;
return numberOfSection;
}
}
Then I have my Fragment code as below which has the the caller to the Async Task
public static class SectionFragment extends Fragment implements OnTaskCompleted {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private Slider adapter;
private ViewPager viewPager;
public static final String ARG_SECTION_NUMBER = "section_number";
Button thumbUpBut;
Button thumbDownBut;
Button captureButton;
ImageView genImage;
TextView genCaption;
private Camera mCamera;
private CameraPreview mPreview;
private static File mediaFile;
private ProgressDialog progress;
private static String imageSaveLocation;
private static String file_name_without_extension;
private ImageView imageView;
private Button uploadButton;
private Button cancelButton;
private Collection<Place> places = null;
private Collection<Happenings> events = null;
private Collection<General> general = null;
private ArrayList<String> sections;
public int getNumberOfPages(){
return sections.size();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy,container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
FeedRequest task = new FeedRequest(this);
task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
captureButton = (Button) rootView.findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePhoto();
}
});
thumbUpBut = (Button) rootView.findViewById(R.id.thumbUp);
thumbUpBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v("thumbPress", "thumbPressUp");
thumb("up");
}
});
thumbDownBut = (Button) rootView.findViewById(R.id.thumbDown);
thumbDownBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v("thumbPress", "thumbPressDown");
thumb("down");
}
});
//allocating the activity one to the camera
if(getArguments().getInt(ARG_SECTION_NUMBER) == 1){
mCamera = getCameraInstance();
mPreview = new CameraPreview(this.getActivity(), mCamera);
FrameLayout preview = (FrameLayout)rootView.findViewById(R.id.camera_preview);
preview.addView(mPreview);
//hide buttons
thumbDownBut.setVisibility(rootView.INVISIBLE);
thumbUpBut.setVisibility(rootView.INVISIBLE);
}else{
thumbDownBut.setVisibility(rootView.VISIBLE);
thumbUpBut.setVisibility(rootView.VISIBLE);
captureButton.setVisibility(rootView.INVISIBLE);
}
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
return rootView;
}
//take photo function
private void takePhoto() {
//get coordinates of the location
UserLocation userLocation = new UserLocation();
userLocation.getUserLocation(getActivity());
coordinates[0] = userLocation.longitude;
coordinates[1] = userLocation.latitude;
PictureCallback pictureCB = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera cam) {
new SavePhotoAndMetadata().execute(data);
cam.startPreview();
}
};
mCamera.takePicture(null, null, pictureCB);
}
//get camera instance
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
//get the media out
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = (DateFormat.format("dd-MM-yyyy hh:mm:ss", new java.util.Date()).toString());
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
file_name_without_extension = "IMG_" + timeStamp;
imageSaveLocation = mediaFile.toString();
return mediaFile;
}
//saving the image and metadata together
class SavePhotoAndMetadata extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... data) {
File picFile = getOutputMediaFile();
if (picFile == null) {
return null;
}
byte[] photoData = data[0];
try {
//save the image
FileOutputStream fos = new FileOutputStream(picFile);
fos.write(photoData);
fos.close();
} catch (FileNotFoundException e) {
e.getStackTrace();
} catch (IOException e) {
e.getStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progress = new ProgressDialog(getActivity());
progress.setMessage("Saving Picture..Please wait...");
progress.show();
}
#Override
protected void onPostExecute(String s) {
progress.dismiss();
imagePreviewDialog();
}
}
//save image metadata in async task
class SaveMetadataTask extends AsyncTask<Void, String, Void> {
#Override
protected Void doInBackground(Void... params) {
serializeDeserialize.serializeData("This is for testing", file_name_without_extension, Double.toString(coordinates[0]), Double.toString(coordinates[1]), deviceId, deviceEmail);
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Void v) {
}
}
//image preview dialog and its functionality
private void imagePreviewDialog(){
//setting the bitmap
Bitmap bmp = BitmapFactory.decodeFile(mediaFile.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Image Preview");
builder.setCancelable(false);
LayoutInflater inflater = getActivity().getLayoutInflater();
ViewGroup vg = (ViewGroup)inflater.inflate(R.layout.sanp_preview_layout, null);
ImageView image = (ImageView) vg.findViewById(R.id.imageView);
image.setImageBitmap(rotateBitmap(bmp));
builder.setView(vg);
//buttons
builder.setPositiveButton("Upload",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(checkInternetConnection.haveNetworkConnection(sContext)){
//upload the image
uploadImage();
//save image metadata
new SaveMetadataTask().execute();
}else{
Toast.makeText(sContext, "Error! No internet connection detected. Image will be uploaded on an active internet connection", Toast.LENGTH_LONG).show();
new SaveMetadataTask().execute();
}
}
});
builder.setNegativeButton("Discard",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
discardImage(mediaFile.toString());
dialog.dismiss();
}
});
builder.show();
}
private Bitmap rotateBitmap(Bitmap image){
int width=image.getHeight();
int height=image.getWidth();
Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig());
for (int y=width-1;y>=0;y--)
for(int x=0;x<height;x++)
srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y));
return srcBitmap;
}
//device email
private String getDeviceEmail(){
AccountManager accountManager = AccountManager.get(sContext);
Account[] account = accountManager.getAccountsByType("com.google");
//device email
for(Account accLoop : account){
deviceEmail = accLoop.name;
}
return deviceEmail;
}
//upload image to the server
private void uploadImage(){
//save metadata
//call upload service
Intent intent = new Intent(sContext, HttpUploader.class);
Bundle loc = new Bundle();
loc.putDoubleArray("ss", coordinates);
intent.putExtra("url", PHOTO_UPLOAD);
intent.putExtra("paths", mediaFile.toString());
intent.putExtra("deviceid", deviceId);
intent.putExtra("deviceemail", getDeviceEmail());
intent.putExtra("posttext", "This is for testing");
intent.putExtra("filename", file_name_without_extension);
intent.putExtra("geo", loc);
sContext.startService(intent);
Toast.makeText(getActivity(), "Your image is being uploaded", Toast.LENGTH_LONG).show();
}
//discard image when the discard button is pressed
private void discardImage(String imagePath){
File file = new File(imagePath);
try{
file.delete();
}catch(Exception e){
Log.e("IMAGE_DELETION_ERROR", e.toString());
}
}
#Override
public void onTaskCompleted(boolean status, String message) {
// TODO Auto-generated method stub
Log.e("onTaskCompleted", "success" + status);
if (message == "tumb UP success") {
thumbUpBut.setSelected(true);
thumbDownBut.setSelected(false);
Log.e("tumb", "tumb");
} else if (message == "tumb DOWN success") {
thumbDownBut.setSelected(true);
thumbUpBut.setSelected(false);
Log.e("tumb", "tumb");
}
}
//listener for fetching main objects
#Override
public void onFeedCompleted(ArrayList<Posts> postArray, Multimap<String, Object> multiMap) {
// TODO Auto-generated method stub
numberOfPages = postArray.size();
adapter = new Slider(getActivity(), postArray, getContext());
viewPager.setAdapter(adapter);
// displaying selected image first
viewPager.setCurrentItem(postArray.size());
//saving the keyset
Set<String> keys = multiMap.keySet();
sections = new ArrayList<String>();
//sorting the categories and creating the category list
for(String key:keys){
//getting category list
if(!sections.contains(keys)){
sections.add(key);
}
//sorting categories
if(key.equals("Place")){
places.add((Place) multiMap.get(key));
}else if(key.equals("Events")){
events.add((Happenings) multiMap.get(key));
}else if(key.equals("General")){
general.add((General) multiMap.get(key));
}
}
}
//adding the pages to the adaptor dynamically
public void addPagesDynamically(){
}
}
//create the parent directory
private void createParentDiectory(){
File dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap");
if(!(dir.exists() && dir.isDirectory())) {
dir.mkdirs();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_post:
openPost();
return true;
case R.id.action_settings:
// openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void openPost() {
/*
Intent i = new Intent(getApplicationContext(), PhotoActivity.class);
startActivity(i);
*/
}
public static void thumb(String type) {
SectionFragment d = new SectionFragment();
PostThumb task = new PostThumb(type, d);
task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
//broadcast receiver for picture upload
public class MyWebRequestReceiver extends BroadcastReceiver {
public static final String PROCESS_RESPONSE = "asia.ceynet.intent.action.PROCESS_RESPONSE";
#Override
public void onReceive(Context context, Intent intent) {
//String responseString = intent.getStringExtra(HttpUploader.RESPONSE_STRING);
String reponseMessage = intent.getStringExtra(HttpUploader.RESPONSE_MESSAGE);
String responseStatus = intent.getStringExtra(HttpUploader.RESPONSE_STATUS);
String file_to_be_deleted = intent.getStringExtra(HttpUploader.FILE_NAME_WITHOUT_EXTENSION);
Toast.makeText(getApplicationContext(), reponseMessage + " - " + file_to_be_deleted + ".jpg", Toast.LENGTH_LONG).show();
//if uploaded successfully delete or image and metadata
if(responseStatus.equals("true")){
File temp_image_dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".jpg");
File metadata_file = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".ser");
try{
temp_image_dir.delete();
metadata_file.delete();
}catch(Exception e){
Log.e("IMAGE_DELETION_ERROR", e.toString());
}
}
}
}
When you finnish pulling the async data, provide the adapter with the new data and call .notifyDataSetChanged() on that adapter instance and the framework will update the pages and count by itself.
If you wish a more detailed explanation post your FragmentPagerAdapter implementation.
First of all, let me apologize if I'm not making myself clear enough because this is one of my first participation(s) here. But I'll be always here to answer queries related to this answer and clear any confusions arose by my statements.
Since you're using fragments, so I'm assuming you must have included your fragments inside an activity (lets say MainActivity.java).
What you need, can be done inside that activity containing fragment.
Here is the example code of onCreate method inside the MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
//Instance of viewpager included inside activity_main.xml
viewPager = (ViewPager) findViewById(R.id.vpMain);
SectionsPagerAdapter adapter = new SectionsPagerAdapter (fragmentManager);
//Adding some fragments right from the beginning, you could ignore it if not needed.
addFragments();
//This `OnPageChangeListener` will do the trick for you.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//Show the title of fragment
Toast.makeText(MainActivity.this, adapter.screens.get(position), Toast.LENGTH_SHORT).show();
//If fragment being loaded is later than the first one,
// then add one more fragment after the last fragment to the adapter.
// integer currentPosition is declared as a field, outside onCreate method and initially set to 0.
if(position>currentPosition){
currentPosition+=1;
adapter.addFragment(new SectionFragment(), "Fragment"+String.valueOf(position+3));
adapter.notifyDataSetChanged();
}else{
currentPosition--;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
} // onCreate ends here.
Create this method inside your MainActivity (just to add 3 fragments to give your application a head-start.
private void addFragments(){
adapter.addFragment(new SectionFragment());
adapter.addFragment(new SectionFragment());
adapter.addFragment(new SectionFragment());
}
Then modify your SectionsPagerAdapter's getItem and getCount methods as below:
public class SectionsPagerAdapter extends FragmentPagerAdapter{
private boolean proceedStatus = false;
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx";
//list of fragments need to be added dynamically
public final ArrayList<Fragment> screens = new ArrayList<Fragment>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return screens.get(position);
}
#Override
public int getCount() {
return screens.size();
}
//This method will dynamically add a fragment each time it is called.
public void addFragment(Fragment fragment) {
screens.add(fragment);
}
Now, no work related to "adding new fragment to the list" needs to be done inside your SectionFragment class.

Categories

Resources