Android - notifydatasetchanged does not work viewpager - java

UPDATED POST:
FriendsFragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
parentView = inflater.inflate(R.layout.fragment_friends, container, false);
recyclerView = (RecyclerView) parentView.findViewById(R.id.list_main);
mArrayList = new ArrayList<>();
bindViews();
setHasOptionsMenu(true);
return parentView;
}
private void bindViews() {
parentActivity = (MainActivity) getActivity();
adapter = new PostThreadAdapter(parentView.getContext(), postsArrayList);
recyclerView.setAdapter(adapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(parentActivity);
recyclerView.setLayoutManager(layoutManager);
getItemsFromDatabase();
}
private getItemsFromDatabase()
{
StringRequest stringRequest = new StringRequest(StringRequest.Method.PUT, "SERVERURL", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
Gson gson = new Gson();
final FeedResponse feedResponse = gson.fromJson(response, FeedResponse.class);
mArrayList.clear();
mArrayList.addAll(feedResponse.getArrayList());
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Log.e("C", "CATH " + e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
};
volley.addRequest(stringRequest, "FriendsFragment");
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Collections.sort(mArrayList, new Comparator<Objectx>() {
#Override
public int compare(Objectx d, Objectx t1) {
return t1.getPostType() - d.getPostType();
}
});
adapter.notifydatasetchanged(); // this only work the first time
}
PROBLEM:
I have 1 Activity (MainActivity)
My activity have framelayout and this can contain 2 fragments.
HomeFragment OR UserFragment
My HomeFragment have TabLayout and viewpager that contain 2 fragments:
Tab1: FriendsFragment
Tab2: NotifiFragment
In my friendsfragment I have recyclerview with custom adapter and viewholder.
This works fine the first time, but when I change of fragment (from HomeFragment to UserFragment) and back again to Homefragment the adapter.notifyDataSetChanged(); don't work anymore. I already tried this:
#Override
public void onResume() {
super.onResume();
array.clear();
getInfoFromDatabase(); // this include .addAll array
adapter.notifyDataSetChanged();
Log.d(TAG, "List Frag Resumed");
}
Also:
#Override
public void onResume() {
super.onResume();
adapter = new CustomAdapter(mView.getContext(), array);
recyclerview.setAdapter(adapter);
getInfoFromDatabase(); // this include .addAll array
adapter.notifyDataSetChanged();
Log.d(TAG, "List Frag Resumed");
}
But none works. I'm also using collections sort to order my items and I notice that the items of the array get changed but can't see in the app because notifydatasetchanged does nothing.

Related

Starting Fragment method from MainActivity causes Exception

I work on an app which contains Fragments and a ViewPager. I fetch location data in my MainActivity and want to use it inside the fragments, so I created a method to pass the variables and process with them. Unfortunately I get a NullPointerException on all view objects, like the progressBar or the CollapsingToolbarLayout inside of the Fragment when the method is called. I guess the fragment is not correctly started just by calling a method, but how can I change it, so the view objects are created? Or is there another way to first fetch location data and use it inside the fragments afterwards?
My MainActivity:
public class MainActivity extends AppCompatActivity implements Serializable {
private ViewPager viewPager;
BottomNavigationView bottomNavigationView;
FragmentA FragmentA;
FragmentB FragmentB;
FragmentC FragmentC;
MenuItem prevMenuItem;
public double lat;
public double lon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_umkreis:
viewPager.setCurrentItem(0);
break;
case R.id.navigation_karte:
viewPager.setCurrentItem(1);
break;
case R.id.navigation_einstellungen:
viewPager.setCurrentItem(2);
break;
}
return false;
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (prevMenuItem != null) {
prevMenuItem.setChecked(false);
}
else
{
bottomNavigationView.getMenu().getItem(0).setChecked(false);
}
Log.d("page", "onPageSelected: "+position);
bottomNavigationView.getMenu().getItem(position).setChecked(true);
prevMenuItem = bottomNavigationView.getMenu().getItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
setupViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
callsFragment = new CallsFragment();
chatFragment = new ChatFragment();
contactsFragment = new ContactsFragment();
adapter.addFragment(callsFragment);
adapter.addFragment(chatFragment);
adapter.addFragment(contactsFragment);
viewPager.setAdapter(adapter);
int limit = adapter.getCount();
viewPager.setOffscreenPageLimit(limit);
}
public void start() {
//Location data fetched here
FragmentB fb = new FragmentB();
fb.start(lat, lon);
}
}
My FragmentB:
public class FragmentB extends Fragment {
private ProgressBar progressBar;
private double lat;
private double lon;
String title;
private BaseAdapter mItemsAdapter;
private final List<HashMap<String, String>> mItemList = new ArrayList<>();
ArrayList<HashMap<String, String>> resultList = new ArrayList<>();
public FragmentB() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_b, container, false);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
((ListView) view.findViewById(R.id.list))
.setAdapter(mItemsAdapter);
return view;
}
public void start(double latGet, double lonGet){
lat = latGet;
lon = lonGet;
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
}
#Override
protected Void doInBackground(Void... arg0) {
//Fetch And Process Data -> Result into resultList
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
final CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) getActivity().findViewById(R.id.toolbar_layout);
AppBarLayout appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.appBar);
progressBar.setVisibility(View.GONE);
//Updating parsed JSON data into ListView
mItemsAdapter = new SimpleAdapter(
getActivity(), mItemList,
R.layout.list_item, new String[]{"brand", "price",
"dist", "street", "houseNumber", "postcode", "place"}, new int[]{R.id.brand,
R.id.price, R.id.dist, R.id.street, R.id.houseNumber, R.id.postCode, R.id.place});
mItemList.addAll(resultList);
mItemsAdapter.notifyDataSetChanged();
}
}
}
In the following method from MainActivity, you try to pass the location data to an instance of FragmentB:
public void start() {
//Location data fetched here
FragmentB fb = new FragmentB();
fb.start(lat, lon);
}
The resulting crash is due to the fact that you only instantiate the Fragment, nothing else. Methods like onCreateView() or onAttach() will only be called if the Fragment is (about to be) added to the View hierarchy. So for this instance of FragmentB, methods like getContext() or getActivity() will return null. That's why you get NullPointerExceptions.
Make sure that you only call start() on a Fragment which has been added to the View hierarchy. Or modify the method so that it stores the location data in some appropriate structure which can be accessed from e.g. onViewCreated(), onStart() or onResume()
See the docs for more information on the Fragment lifecycle

ClassCastException error when using setOnScrollListener

Below is a code where data will come at scrolling time but there is an error i.e
ClassCastException. Please help me to solve this error. Now I have added my whole fragment class Similar_Matchs_Tab where we fetching the from server.
java.lang.ClassCastException: com.devbhoomimedia.maangal.ProfilesActivity cannot be cast to android.widget.AbsListView$OnScrollListener
public class Similar_Matchs_Tab extends Fragment {
private ListView listView;
public Similar_Matchs_Tab() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
JSON_URL = "https://www.maangal.com/maangal_mobile/similar_matches.php?matri_id="+email;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Inflate the layout for this fragment
View view= inflater.inflate(R.layout.matches_tab, container, false);
listView = (ListView) view.findViewById(R.id.listView);
listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity());
sendRequest();
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});
return view;
}
sendRequest function to fetch the data
private void sendRequest(){
final ProgressDialog loading = ProgressDialog.show(getActivity(),"Loading Data", "Please wait...",false,false);
StringRequest stringRequest = new StringRequest(Request.Method.POST,JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
loading.dismiss();
showJSON(response);
Log.e("Similar MAtches******",response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(),error.getMessage(), Toast.LENGTH_LONG).show();
}
});
int MY_SOCKET_TIMEOUT_MS = 30000;
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(stringRequest);
}
protected void showJSON(String json){
ParseJSON pj = new ParseJSON(json);
pj.parseJSON();
Profile_Match_custom_List cl = new Profile_Match_custom_List(getActivity(), ParseJSON.ids,ParseJSON.ages, ParseJSON.heights, ParseJSON.communities,ParseJSON.castes,ParseJSON.educations,ParseJSON.occupations,ParseJSON.incomes,ParseJSON.pics,ParseJSON.locations,ParseJSON.shortlist,ParseJSON.expressinterest);
listView.setAdapter(cl);
}
}
B'coz you're casting Activity into AbsListView.OnScrollListener interface that's why you're getting classCastException.
just remove listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity());
and replace
listView.setOnScrollListener((ProfileActivity) getActivity());
The reason why you're getting this error is because you're trying to cast activity to a scroll listener which is not possible. So to fix the problem just set the appropriate interface and it should work. Replace listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity()); with this:
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});
change it
listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity());
to
listView.setOnScrollListener((ProfileActivity)getActivity());
and ProfileActivity must implements AbsListView.OnScrollListener.
Your activity does not implement AbsListView.OnScrollListener interface.

Custom Listview Won't Display with Volley Request

I have created a Custom Listview that will display area list from my database but sometimes the data won't display. After staying in the activity for a couple of seconds and restarting the activity again it will display the list. Here is my code can you check this out ? If see what's the problem. Thanks!
AreaListActivity.java
private ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setupActionBar();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
#Override
protected void onResume() {
super.onResume();
setupList();
}
#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, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
finish(); // close this activity and return to preview activity (if there is any)
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Only if you need to restore open/close state when
// the orientation is changed
if (adapter != null) {
adapter.saveStates(outState);
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Only if you need to restore open/close state when
// the orientation is changed
if (adapter != null) {
adapter.restoreStates(savedInstanceState);
}
}
private void setupList() {
ListView listView = (ListView) findViewById(R.id.list_view);
adapter = new ListAdapter(this, createList());
listView.setAdapter(adapter);
}
private List<String> createList() {
final List<String> list = new ArrayList<>();
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String areaName = obj.getString("area_name");
list.add(areaName);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
GetAreaListRequest registerRequest = new GetAreaListRequest("True", responseListener);
RequestQueue queue = Volley.newRequestQueue(AreaListActivity.this);
queue.add(registerRequest);
return list;
}
private void setupActionBar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
}
GetAreaListRequest.java
public class GetAreaListRequest extends StringRequest {
private static final String GET_AREA_LIST_URL = "http://192.168.1.7:8080/smsams/get_area_list.php";
private Map<String, String> params;
public GetAreaListRequest(String get_area_status, Response.Listener<String> listener) {
super(Method.POST, GET_AREA_LIST_URL, listener, null);
params = new HashMap<>();
params.put("get_area_status", get_area_status);
}
#Override
public Map<String, String> getParams() {
return params;
}
ListAdapter.java
class ListAdapter extends ArrayAdapter<String> {
private final LayoutInflater mInflater;
private final ViewBinderHelper binderHelper;
private Context context;
ListAdapter(Context context, List<String> objects) {
super(context, R.layout.row_list, objects);
mInflater = LayoutInflater.from(context);
binderHelper = new ViewBinderHelper();
this.context = context;
// uncomment if you want to open only one row at a time
// binderHelper.setOpenOnlyOne(true);
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row_list, parent, false);
holder = new ViewHolder();
holder.textView = (TextView) convertView.findViewById(R.id.text);
holder.statView = convertView.findViewById(R.id.statistic_layout);
holder.mapView = convertView.findViewById(R.id.map_layout);
holder.infoView = convertView.findViewById(R.id.info_layout);
holder.swipeLayout = (SwipeRevealLayout) convertView.findViewById(R.id.swipe_layout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final String item = getItem(position);
if (item != null) {
binderHelper.bind(holder.swipeLayout, item);
holder.textView.setText(item);
holder.statView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, StatisticActivity.class);
context.startActivity(i);
}
});
holder.mapView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, MapsActivity.class);
i.putExtra("soilArea", holder.mapView.toString());
context.startActivity(i);
}
});
holder.infoView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, InfoViewActivity.class);
context.startActivity(i);
}
});
}
return convertView;
}
/**
* Only if you need to restore open/close state when the orientation is changed.
* Call this method in {#link android.app.Activity#onSaveInstanceState(Bundle)}
*/
void saveStates(Bundle outState) {
binderHelper.saveStates(outState);
}
/**
* Only if you need to restore open/close state when the orientation is changed.
* Call this method in {#link android.app.Activity#onRestoreInstanceState(Bundle)}
*/
void restoreStates(Bundle inState) {
binderHelper.restoreStates(inState);
}
private class ViewHolder {
TextView textView;
View statView;
View mapView;
View infoView;
SwipeRevealLayout swipeLayout;
}
Try this:
private List<String> list = new ArrayList<>();
private void setupList() {
ListView listView = (ListView) findViewById(R.id.list_view);
adapter = new ListAdapter(this, list);
listView.setAdapter(adapter);
}
private void createList() {
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String areaName = obj.getString("area_name");
list.add(areaName);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
};
GetAreaListRequest registerRequest = new GetAreaListRequest("True", responseListener);
RequestQueue queue = Volley.newRequestQueue(AreaListActivity.this);
queue.add(registerRequest);
}
The network requests usually happens in an asynchronous way. So there is no specific time that the onResponse() gets called. So in your createList() method you initialised an empty arraylist and before the request produces the response(asynchronously calls onResponse) the list which contains no value is returned.
You can change your code something like this:
In createList():
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String areaName = obj.getString("area_name");
list.add(areaName);
adapter = new ListAdapter(this, list);
listView.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
So here the adapter is set only after the data is pulled from the network.

Refresh fragments after coming back from an activity

I'm working on an activity which uses a TabLayout to house two fragments. Each of the fragments uses RecyclerView. The activity also has an options menu. When any of the options is clicked, a new activity will start. One of the new activities has a "Save" button which when clicked will update the first activity's data set and return to the first activity. However, the first activity's fragments don't show the changed data set even though the data set itself changes.
RecordAddActivity.java (First Activity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FileUtils.initDataDir(this);
MySQLiteHelper db = new MySQLiteHelper(this);
Bundle bundle = getIntent().getExtras();
siteID = bundle.getLong(Constants.INTENT_EXTRA_SITE_ID);
site = db.getSiteByID(siteID);
trapFileName = site.getId() + "_" + site.getName() + ".csv";
inputString = site.getName();
setContentView(R.layout.activity_add_record_new);
viewPager = (ViewPager) findViewById(R.id.view_pager);
adapter = new PagerAdapter(getSupportFragmentManager());
insectsAddRecordFragment = new InsectsAddRecordFragment();
naturalPestsAddRecordFragment = new NaturalPestsAddRecordFragment();
if (!doesRecordExist) {
insectsAddRecordFragment.setInsects(site.getInsectsNames());
naturalPestsAddRecordFragment.setNaturalPests(site.getNaturalPestsNames());
} else {
IsDefaultInsectTypes isDefaultInsectTypes = new IsDefaultInsectTypes(trapFileName);
insectsAddRecordFragment.setInsects(isDefaultInsectTypes.getInsectNamesList());
naturalPestsAddRecordFragment.setNaturalPests(isDefaultInsectTypes.getPestNamesList());
site.setInsects(isDefaultInsectTypes.getInsectNamesList());
site.setNaturalPests(isDefaultInsectTypes.getPestNamesList());
}
adapter.addFragment(insectsAddRecordFragment, "Serangga Perosak");
adapter.addFragment(naturalPestsAddRecordFragment, "Musuh Semulajadi");
viewPager.setAdapter(adapter);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tablayoutbar);
tabLayout.setTabTextColors(Color.BLACK, Color.WHITE);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
tabLayout.requestFocus();
hideKeyboard(viewPager);
}
});
}
//The options menu which start the new activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_edit_insects_type){
final int EDIT_INSECT_TYPE_REQUEST = 1;
Intent intent = new Intent(RecordAddActivity.this, EditInsectsTypeActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_REPORT_TRAP_FILE, trapFileName);
intent.putExtra(Constants.INTENT_EXTRA_SITE_OBJECT, site);
startActivityForResult(intent, EDIT_INSECT_TYPE_REQUEST);
return true;
}
}
//The FragmentPagerAdapter
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragmentList = new ArrayList<>();
private List<String> mFragmentTitleNames = new ArrayList<>();
public PagerAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleNames.add(title);
}
public void swapItems(Fragment insectFragment, Fragment naturalPestFragment) {
mFragmentList.clear();
mFragmentList.add(insectFragment);
mFragmentList.add(naturalPestFragment);
Log.d(TAG, "Items swapped");
notifyDataSetChanged();
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleNames.get(position);
}
}
What I've tried:
Using onResume()
#Override
public void onResume() {
Log.d(TAG, "onResume");
super.onResume(); // Always call the superclass method first
doesRecordExist = FileUtils.doesRecordExists(trapFileName);
if (doesRecordExist) {
IsDefaultInsectTypes isDefaultInsectTypes = new IsDefaultInsectTypes(trapFileName);
insectsAddRecordFragment = new InsectsAddRecordFragment();
naturalPestsAddRecordFragment = new NaturalPestsAddRecordFragment();
//The log shows that the data set has changed
Log.d(TAG, "Nama serangga:" + isDefaultInsectTypes.getInsectNamesList());
//Trying to update the fragments
insectsAddRecordFragment.setInsects(isDefaultInsectTypes.getInsectNamesList());
naturalPestsAddRecordFragment.setNaturalPests(isDefaultInsectTypes.getPestNamesList());
adapter.swapItems(insectsAddRecordFragment, naturalPestsAddRecordFragment);
}
}
Using a Global variable to update the fragment
EditInsectsTypeActivity.java (The new activity)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_save) {
Globals2 allowRefresh = Globals2.getInstance();
ArrayList<String> insectsNameList = insectsViewFragment.getInsectsNameList();
ArrayList<String> pestsNameList = naturalPestsViewFragment.getInsectsNameList();
FileUtils.updateSiteInsects(this, trapFileName, insectsNameList, pestsNameList);
allowRefresh.setData(true);
Log.d(TAG, "allowRefresh: " + allowRefresh.getData());
finish();
Utils.showToast(getBaseContext(), "Rekod disimpan");
}
return true;
}
InsectsAddRecordFragment.java (The fragment to be refreshed/updated)
#Override
public void onResume() {
Log.d(TAG, "onResume");
super.onResume(); // Always call the superclass method first
Globals2 allowRefresh = Globals2.getInstance();
IsDefaultInsectTypes isDefaultInsectTypes = new IsDefaultInsectTypes("27_Cgtv.csv");
Log.d(TAG, "Nama serangga:" + isDefaultInsectTypes.getInsectNamesList());
setInsects(isDefaultInsectTypes.getInsectNamesList());
Log.d(TAG, "allowRefresh: " + allowRefresh.getData());
if (allowRefresh.getData()) {
allowRefresh.setData(false);
getFragmentManager().beginTransaction().detach(this).attach(this).commit();
}
}
I've spent hours trying to fix this without any luck. Any help will be much appreciated.
So here's what you need to do, in your Activity's onPause() method update the list in your InsectsAddRecordFragment like so:
public void onPause()
{
... // your logic for data-set changed.
if (doesRecordExist)
insectsAddRecordFragment.setInsects(isDefaultInsectTypes.get‌​InsectNamesList());
...
}
And within setInsects of InsectsAddRecordFragment something similar to this.
public void setInsects() {
// Here adapter is the Adapter for the RecyclerView
adapter.setAdapterList(isDefaultInsectTypes.get‌​InsectNamesList());
// notifyDataSetChanged() is important here because without this the Adapter has no idea
// that data has changed.
adapter.notifyDataSetChanged();
}
While in your RecyclerViewAdapter for InsectsAddRecordFragment's RecyclerView items. Do the following.
// ArrayList<String> list is just an example you may have some different data set.
public void setAdapterList(ArrayList<String> list) {
this.adapterList = list;
}
Using this approach there is no need recreate the fragment, instead you can just update the dataset within the Adapter.
I'd also suggest reading some blogs and how-to's on Fragments, RecyclerView and RecyclerView.Adapter before you work any further.
Override:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
In the first Activity.
[EDIT] More info on startActivityForResult() here:
https://developer.android.com/training/basics/intents/result.html

How to improve classes ? Issue with inner classes [Android]

I'm using Android Studio to develop my app. I have two activities that does the same thing (except a parameter value) and I have an inner class inside which does the same thing too in the other activity. My inner class extends AsyncTask for background downloading. But, if I extend my second activity from my 1st activity, I can't do task.execute(), I will need to extend AyncTask too,and extending from two classes impossible in Java.. Here's my code :
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private TextView title;
private List<User> myList;
String query_url;
MyAdapter myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycler = (RecyclerView) findViewById(R.id.recyclerView);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recycler.setLayoutManager(llm);
//create and execute new task
AsyncDL task = new AsyncDL();
task.execute();
}
//background download
private class AsyncDL extends AsyncTask<Object, String, Integer> {
#Override
protected Integer doInBackground(Object... params) {
tryDownloadXmlData();
return null;
}
private void tryDownloadXmlData() {
try {
URL xmlUrl = new URL(query_url);
myXMLPullParser myCustomParser = new myXMLPullParser();
//fetch & parse data
myList = myCustomParser.parse(xmlUrl.openStream());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Integer integer) {
myAdapter = new MyAdapter(getApplicationContext(), myList);
recycler.setAdapter(myAdapter);
RecyclerItemClickSupport.addTo(recycler).setOnItemClickListener(new RecyclerItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
User user = myList.get(position);
Intent myIntent = new Intent(getApplicationContext(), Details.class);
myIntent.putExtra("user", user);
startActivity(myIntent);
}
});
super.onPostExecute(integer);
}
}
}
I don't really know if it is possible to reuse an activity's code like that, thanks !
EDIT: new piece of code
ProductAsyncTask task = new ProductAsyncTask(getApplicationContext(), listview, QUERY_URL, productList, myCustomAdapter);
task.execute();
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
User currentUser = myList.get(position); //error here
Intent myIntent = new Intent(getApplicationContext(), Detail_User.class);
myIntent.putExtra("currentUser", currentUser);
Log.i("INFO", "Loading extra data for transfer...");
startActivity(myIntent);
}
});

Categories