I have tested my app with the emulator and everything works as expected. now im debugging the app via usb debugging. This is when i get this issue. I have a ListView in my app. When the user press a List Item it starts a new activity. My issue is, after the user press the back button, the ListView is not generated again. I just a blank activity.Even if i restart the app, when i go to the activity that contains the ListView, it wont generate the ListView. The only way to fix this is to clear the data of my application via my phone settings. What is causing this issue? Why is it working well with the emulator and not with my phone? (Im using a Xiaomi Mi4) any help would be much appreciated.
CustomListAdapter
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Guide> guideItems;
public CustomListAdapter(Activity activity, List<Guide> guideItems) {
this.activity = activity;
this.guideItems = guideItems;
}
#Override
public int getCount() {
return guideItems.size();
}
#Override
public Object getItem(int location) {
return guideItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.customrow, parent, false);
TextView ngno = (TextView) convertView.findViewById(R.id.txt_ListNgno);
TextView name = (TextView) convertView.findViewById(R.id.txt_ListName);
TextView email = (TextView) convertView.findViewById(R.id.txt_ListEmail);
// getting movie data for the row
Guide g = guideItems.get(position);
ngno.setText(g.getNgno());
name.setText(g.getName());
email.setText(g.getEmail());
return convertView;
}
}
This is the activity that implements the ListView.
public class ViewGuidesActivity extends AppCompatActivity {
private static final String TAG = ViewGuidesActivity.class.getSimpleName();
private ProgressDialog pDialog;
private List<Guide> guideList = new ArrayList<Guide>();
private ListView listView;
private CustomListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_guides);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this, guideList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(AppConfig.URL_GET_GUIDE_LIST,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Guide guide = new Guide();
guide.setNgno(obj.getString("ngno"));
guide.setEmail(obj.getString("email"));
guide.setName(obj.getString("name"));
// adding movie to movies array
guideList.add(guide);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, error.toString());
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
Guide newGuide = guideList.get(position);
String email = newGuide.getEmail();
String ngno = newGuide.getNgno();
//System.out.println(email);
Intent i = new Intent(getApplicationContext(), GuideDetails.class);
i.putExtra("email", email);
i.putExtra("ngno", ngno);
startActivity(i);
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
#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_main, menu);
menu.getItem(1).setVisible(false);
menu.getItem(2).setVisible(false);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Related
anyone know how to display details item in other fragment detail when everytime im click item from listview? and how to set them? and anyone have an example for this?
in listview only show :
- Nama, gambar1, tipe, mainmuscle, othermuscle, alat, rating on details fragment i want to show :
-Nama, gambar1, tipe, mainmuscle, othermuscle, alat, rating, deskripsi, gambar2, gambar3, gambar4
here my code :
Fragment.java
public class AbdominalFragment extends Fragment {
// Log tag
private static final String TAG = AbdominalFragment.class.getSimpleName();
// Movies json url
private static final String url = "http.......";
private ProgressDialog pDialog;
private List<Exercise> exerciseList = new ArrayList<Exercise>();
private ListView listView;
private CustomListAdapter adapter;
public AbdominalFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_list, container, false);
// Inflate the layout for this fragment
final ListView listView = (ListView) rootView.findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), exerciseList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
if(exerciseList.isEmpty()) {
// Creating volley request obj
JsonArrayRequest exerciseReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
exerciseList.clear();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Exercise exercise = new Exercise();
if (obj.getString("tipe").equals("abdominal")) {
exercise.setNama(obj.getString("nama"));
exercise.setGambar1(obj.getString("gambar1"));
exercise.setTipe(obj.getString("tipe"));
exercise.setMainmuscle(obj.getString("mainmuscle"));
exercise.setAlat(obj.getString("alat"));
exercise.setTipe(obj.getString("othermuscle"));
exercise.setRating(obj.getDouble("rating"));
// adding exercise to exercise array
exerciseList.add(exercise);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(exerciseReq);
}else{
hidePDialog();
}
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
listView.setOnItemClickListener(this);
make your fragment implements AdapterView.OnItemClickListener
public class AbdominalFragment extends Fragment implements AdapterView.OnItemClickListener
now onClick
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Create custom dialog object
final Dialog dialog = new Dialog(context);
// Include dialog.xml file
dialog.setContentView(R.layout.dialog); // layout of your dialog
// Set dialog title
dialog.setTitle("Detail");
// set values for custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.textDialog);
text.setText(exerciseList.get(position).getNama());
// similar add statements for other details
dialog.show();
}
layout for dialog dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/textDialog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:layout_toRightOf="#+id/imageDialog"/>
</RelativeLayout>
Try this in onCreate():
ListView list = (ListView) rootView.findViewById(R.id.listView);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked,int position, long id) {
ArrayList clickedItem = exerciseList.get(position);
//Here you can hadle your Views....
}
});
My suggestion would be to use interface to send call back to the activity that holds your AbdominalFragment from OnItemClickListener of ListView.
And according to that your activity can replace the AbdominalFragment with Details Fragment.
For communicating with activity see the below link
http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
You could extend the Listfragment and overrride the onListItemClicked method.
like this,
public class AbdominalFragment extends ListFragment {
String[] MONTHS = { "jan", "feb", "march", "april", "may", "june", "july",
"august", "sep", "octo", "nov", "dec" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
inflater.getContext(), android.R.layout.simple_list_item_1,
MONTHS);
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
Toast.makeText(getActivity(), "selected month :" + MONTHS[position],
Toast.LENGTH_LONG).show();
}
}
I know that this question is asked 100 times, but for some reason i cannot find what is wrong in my code.
I am very new to android and java.
Basically i have a wordpress website from which I want to get the articles. I have installed the wp-rest-api v2 to get the data in json array format.
In my android app I have
MainActivity.java
package al.im.imp;
/*ALL THE IMPORTS*/
public class ImpHome extends AppCompatActivity implements View.OnClickListener {
ListView lstTest;
JSONAdapter mJSONAdapter;
Button search_Button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imp_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
//Access Listview
lstTest = (ListView) findViewById(R.id.home_list);
search_Button = (Button) findViewById(R.id.button1);
search_Button.setOnClickListener(this);
mJSONAdapter = new JSONAdapter(this, getLayoutInflater());
lstTest.setAdapter(mJSONAdapter);
}
#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_impakt_home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void queryImp() {
// Create a client to perform networking
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://example.com/wp-json/wp/v2/posts",
new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONArray jsonArray) {
Toast.makeText(getApplicationContext(), "Success!", Toast.LENGTH_LONG).show();
mJSONAdapter.updateData(jsonArray);
}
#Override
public void onFailure(int statusCode, Throwable throwable, JSONObject error) {
// Display a "Toast" message
// to announce the failure
Toast.makeText(getApplicationContext(), "Error: " + statusCode + " " + throwable.getMessage(), Toast.LENGTH_LONG).show();
// Log error message
// to help solve any problems
Log.e("Imp android", statusCode + " " + throwable.getMessage());
}
});
}
#Override
public void onClick(View v) {
queryImp();
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
}
My article_list.xml layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="75dp">
<TextView
android:id="#+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"/>
</RelativeLayout>
and my JSONAdapter.java class
package al.imp.imp;
/*IMPORTS*/
public class JSONAdapter extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
JSONArray mJsonArray;
public JSONAdapter(Context context, LayoutInflater inflater) {
mContext = context;
mInflater = inflater;
mJsonArray = new JSONArray();
}
#Override
public int getCount() {
return mJsonArray.length();
}
#Override
public Object getItem(int position) {
return mJsonArray.optJSONObject(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.article_list, null);
holder = new ViewHolder();
holder.titleTextView = (TextView) convertView.findViewById(R.id.text_title);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
JSONObject jsonObject = (JSONObject) getItem(position);
String articleTitle = "";
articleTitle = jsonObject.optJSONObject("title").optString("rendered");
holder.titleTextView.setText(articleTitle);
return convertView;
}
private static class ViewHolder {
public TextView titleTextView;
}
public void updateData(JSONArray jsonArray) {
// update the adapter's dataset
mJsonArray = jsonArray;
notifyDataSetChanged();
}
}
I dont know why this does not work. When i try to log the data like
for (int i = 1; i < jsonArray.length(); i++) {
Log.d("Title is:", jsonArray.optJSONObject(i).getJSONObject("title").getString("rendered").toString());
Log.d("Image Url is:", jsonArray.optJSONObject(i).getString("featured_image_thumbnail_url").toString());
}
it works perfectly, so I guess it is not a problem in getting the json response, but populating the listview.
Help me please
After updating the data, try something like refreshing the list view like lstTest.invalidateViews(); - so your queryImp() code will change into:
private void queryImp() {
// Create a client to perform networking
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://example.com/wp-json/wp/v2/posts",
new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONArray jsonArray) {
Toast.makeText(getApplicationContext(), "Success!", Toast.LENGTH_LONG).show();
mJSONAdapter.updateData(jsonArray);
mJSONAdapter.notifyDataSetChanged();
//try refreshing the list-view like this:
lstTest.invalidateViews()
}
#Override
public void onFailure(int statusCode, Throwable throwable, JSONObject error) {
// Display a "Toast" message
// to announce the failure
Toast.makeText(getApplicationContext(), "Error: " + statusCode + " " + throwable.getMessage(), Toast.LENGTH_LONG).show();
// Log error message
// to help solve any problems
Log.e("Imp android", statusCode + " " + throwable.getMessage());
}
});
}
Let me know if the changes help.
I have 2 fragment( Fragment A and fragment B) with functions to load data using .json.
When I click fragment A, the data will load, and when I click fragment B the data will load too.
When I click fragment A another time, the data is reloaded and duplicated (appended with the data from the first click).
How to stop loading data if data is already loaded?
example image
here my fragment code
fragment_a.java
public class fragment_a extends Fragment {
// Log tag
private static final String TAG = MovieFragment1.class.getSimpleName();
// Movies json url
private static final String url = "http://.......";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomListAdapter adapter;
public MovieFragment1() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_list, container, false);
// Inflate the layout for this fragment
final ListView listView = (ListView) rootView.findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Movie movie = new Movie();
if (obj.getString("tipe").equals("chest")){
movie.setTitle(obj.getString("name"));
movie.setThumbnailUrl(obj.getString("images1"));
//movie.setDescribe(obj.getString("describe"));
//movie.setRating(((Number) obj.get("rating"))
// .doubleValue());
movie.setYear(obj.getInt("id"));
movie.setTipe(obj.getString("tipe"));
/*// Genre is json array
JSONArray genreArry = obj.getJSONArray("genre");
ArrayList<String> genre = new ArrayList<String>();
for (int j = 0; j < genreArry.length(); j++) {
genre.add((String) genreArry.get(j));
}
movie.setGenre(genre);*/
// adding movie to movies array
movieList.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
fragment_b.java
public class fragment_b extends Fragment {
// Log tag
private static final String TAG = MovieFragment1.class.getSimpleName();
// Movies json url
private static final String url = "http://......";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomListAdapter adapter;
public MovieFragment1() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_list, container, false);
// Inflate the layout for this fragment
final ListView listView = (ListView) rootView.findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Movie movie = new Movie();
if (obj.getString("tipe").equals("forearm")){
movie.setTitle(obj.getString("name"));
movie.setThumbnailUrl(obj.getString("images1"));
//movie.setDescribe(obj.getString("describe"));
//movie.setRating(((Number) obj.get("rating"))
// .doubleValue());
movie.setYear(obj.getInt("id"));
movie.setTipe(obj.getString("tipe"));
/*// Genre is json array
JSONArray genreArry = obj.getJSONArray("genre");
ArrayList<String> genre = new ArrayList<String>();
for (int j = 0; j < genreArry.length(); j++) {
genre.add((String) genreArry.get(j));
}
movie.setGenre(genre);*/
// adding movie to movies array
movieList.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
tabfragment.java (fragment adapter)
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 3 ;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**
*Inflate tab_layout and setup Views.
*/
View x = inflater.inflate(R.layout.tab_layout,null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
/**
*Set an Apater for the View Pager
*/
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
/**
* Now , this is a workaround ,
* The setupWithViewPager dose't works without the runnable .
* Maybe a Support Library Bug .
*/
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
/**
* Return fragment with respect to Position .
*/
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new fragment_a();
case 1 : return new HomeFragment();
case 2 : return new fragment_b();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
/**
* This method returns the title of the tab according to the position.
*/
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Chest";
case 1 :
return "Movie";
case 2 :
return "Forearm";
}
return null;
}
}
}
Just wrap your movieRequest with
if(movieList.isEmpty()){
JsonArrayRequest movieReq = new JsonArrayRequest(url, ... ETC...
// etc
}
But remember that with this approach your data will not update if it is changed on server, to make it updatable you must clear movieList before filling it every time instead:
movieList.clear();
In my project a read data from a CMS I created through a JSON response. My problem is when I click the refresh button the data are read twice!. Here is my fragment's code.
public class FootballNews extends Fragment {
public static final String TAG = "ManuApp";
private static final String IMAGE_URL = "http://xxx//manucms/football_news_images/" ;
private List<FootballNewsObject> listItemsList;
private RecyclerView mRecyclerView;
private FootballNewsAdapter adapter;
public FootballNews() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRetainInstance(true);
View v = inflater.inflate(R.layout.fragment_football_news, container, false);
// Inflate the layout for this fragment
listItemsList = new ArrayList<FootballNewsObject>();
mRecyclerView = (RecyclerView)v.findViewById(R.id.recycler_view);
//mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).color(Color.BLACK).build());
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(linearLayoutManager);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
updateList();
}
public void updateList() {
//declare the adapter and attach it to the recyclerview
adapter = new FootballNewsAdapter(getActivity(), listItemsList);
mRecyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(getActivity());
// Clear the adapter because new data is being added from a new subreddit
//adapter.clearAdapter();
//showPD();
// Request a string response from the provided URL.
JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, Config.URL_FOOTBALL_NEWS, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
//hidePD();
// Parse json data.
// Declare the json objects that we need and then for loop through the children array.
// Do the json parse in a try catch block to catch the exceptions
try {
for (int i = 0; i < response.length(); i++) {
JSONObject post = response.getJSONObject(i);
FootballNewsObject item = new FootballNewsObject();
item.setTitle(post.getString("title"));
item.setImage(IMAGE_URL + post.getString("news_image"));
item.setArticle(post.getString("article"));
listItemsList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
// Update list by notifying the adapter of changes
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
//hidePD();
}
});
jsObjRequest.setRetryPolicy(new RetryPolicy() {
#Override
public int getCurrentTimeout() {
return 50000;
}
#Override
public int getCurrentRetryCount() {
return 50000;
}
#Override
public void retry(VolleyError error) throws VolleyError {
}
});
queue.add(jsObjRequest);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
getActivity().getMenuInflater().inflate(R.menu.main, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if(id == R.id.refresh){
if(isOnline()) {
updateList();
}else{
Toast.makeText(getActivity(),"There is no internet connection",Toast.LENGTH_SHORT).show();
}
}
return super.onOptionsItemSelected(item);
}
protected boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
}
Basically I am running the updateList method twice. Once in the onActivityCreated(...) method,and secondly inside the onOptionsItemSelected(...).
Finally here is my adapter.
public class FootballNewsAdapter extends RecyclerView.Adapter<FootballNewsRowHolder>{
private List<FootballNewsObject> footballNewsObjectList;
private Context mContext;
private ImageLoader mImageLoader;
private int focused = 0;
public FootballNewsAdapter(Activity activity, List<FootballNewsObject> footballNewsObjectList){
this.footballNewsObjectList = footballNewsObjectList;
this.mContext = activity;
}
#Override
public FootballNewsRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.football_news_row,null);
final FootballNewsRowHolder holder = new FootballNewsRowHolder(v);
return holder;
}
#Override
public void onBindViewHolder(FootballNewsRowHolder holder, int position) {
final FootballNewsObject listItems = footballNewsObjectList.get(position);
holder.itemView.setSelected(focused==position);
holder.getLayoutPosition();
mImageLoader = AppController.getInstance().getImageLoader();
holder.thumbnail.setImageUrl(listItems.getImage(),mImageLoader);
holder.thumbnail.setDefaultImageResId(R.drawable.reddit_placeholder);
holder.name.setText(Html.fromHtml(listItems.getTitle()));
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = listItems.getTitle();
String article = listItems.getArticle();
String image = listItems.getImage();
Intent i = new Intent(mContext, Extras.class);
i.putExtra("title",title);
i.putExtra("article",article);
i.putExtra("image",image);
mContext.startActivity(i);
//Toast.makeText(mContext,"You clicked",Toast.LENGTH_SHORT).show();
//Intent intent = new Intent(mContext,WebActivity.class);
//intent.putExtra("url",postUrl);
// mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return (null != footballNewsObjectList?footballNewsObjectList.size() :0 );
}
}
Any ideas?
Thanks
You are adding to your list in your refresh method, instead of updating. Add
listItemsList.clear();
at the beginning of your refresh function (updateList).
In my app there is a fragment class (TabFragmentComerTiposRestaurante). It has also two tab fragments in it (Case 0: PrimaryFragmentComerTiposRestaurante, Case 1: SocialFragmentComerTiposRestaurante).
On both fragment classes there is a listview. When clicking on an item from this list, another fragment class is shown (PrimaryFragmentComer.
Shorty this the schema:
TabFragmentComerTiposRestaurante(#F1)
-[PrimaryFragmenComerTiposRestaurante](#F11)--[PrimaryFragmentComer](#F111)
-[SocialFragmentComerTiposRestaurante](#F12)--[SocialFragmentComer](#F121)
The issue I need to solve is the following:
If at (#F111) or at (#F121) the users click on the back button, then the listview items from #F11 and #F12 are loaded again. That means, if on the first #F11 call there is an item called "Cocina americana", then going back from #F111 to #F11 or going back from #F121 to #F12, there are now two equal items: First row=Cocina americana, Second row=Cocina americana. And that happens every time the user goes from #F11 or #F12 to #F111 or #F112.
Here you can find the code for
F1:
public class TabFragmentComerTiposRestaurante extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 2 ;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**
*Inflate tab_layout and setup Views.
*/
View x = inflater.inflate(R.layout.tab_layout_tipo_rte,null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
/**
*Set an Apater for the View Pager
*/
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
/**
* Now , this is a workaround ,
* The setupWithViewPager dose't works without the runnable .
* Maybe a Support Library Bug .
*/
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
/**
* Return fragment with respect to Position .
*/
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new PrimaryFragmentComerTiposRestaurante();
case 1 : return new SocialFragmentComerTiposRestaurante();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
/**
* This method returns the title of the tab according to the position.
*/
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "CIUDAD JUAREZ";
case 1 :
return "EL PASO";
}
return null;
}
}
}
Code for #F11
public class PrimaryFragmentComerTiposRestaurante extends Fragment implements AdapterView.OnItemClickListener {
private OnFragmentInteractionListener mListener;
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// Movies json url
private static final String url = "..hiddene here";
private ProgressDialog pDialog;
private List<TipoRestaurante> tipoRestauranteList = new ArrayList<TipoRestaurante>();
private ListView listView;
private CustomListAdapterTipoRte adapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.primary_layout_tiporte, null);
}
#Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
listView = (ListView) getView().findViewById(R.id.list);
adapter = new CustomListAdapterTipoRte (getActivity(), tipoRestauranteList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Procesando tipos..");
pDialog.show();
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
Log.d("estoy aqui","estoy");
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
TipoRestaurante restaurante = new TipoRestaurante();
restaurante.setId_tipo(obj.getInt("id_tipo"));
restaurante.setNombre_tipo(obj.getString("nombre_tipo"));
restaurante.setFoto_tipo(obj.getString("foto_tipo"));
Log.d(TAG, response.toString());
// adding movie to movies array
tipoRestauranteList.add(restaurante);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage(obj.optString("id_tipo"));
// pDialog.show();
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TipoRestaurante rteActual = (TipoRestaurante) adapter.getItem(position);
String msg = "Has elegido el tipo " + rteActual.getNombre_tipo();
Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
Fragment newFragment = new PrimaryFragmentComer();
Bundle args = new Bundle();
args.putInt("myIntLabel", 2);
args.putString("myStringLabel", rteActual.getNombre_tipo());
//and you can add all you want to that bundle like this
newFragment.setArguments(args);
if (mListener != null) {
mListener.onFragmentInteraction(newFragment);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Fragment fragment);
}
}
And now code for #F111:
public class PrimaryFragmentComer extends Fragment implements AdapterView.OnItemClickListener {
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// Movies json url
private static final String url = "...hidden here";
private ProgressDialog pDialog;
private List<Restaurante> restauranteList = new ArrayList<Restaurante>();
private ListView listView;
private CustomListAdapterRte adapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.primary_layout_comer, null);
}
#Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
String hola = args.getString("myStringLabel");
Log.d("TIPO RTE", hola);
listView = (ListView) getView().findViewById(R.id.list);
adapter = new CustomListAdapterRte (getActivity(), restauranteList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Procesando restaurantes...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url+hola,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Restaurante restaurante = new Restaurante();
restaurante.setId_rte(obj.getInt("id_rte"));
restaurante.setNombre(obj.getString("nombre_rte"));
restaurante.setDescripcion(obj.getString("descripcion_rte"));
restaurante.setLatitud(obj.getDouble("latitud_rte"));
restaurante.setLongitud(obj.getDouble("longitud_rte"));
restaurante.setDireccion(obj.getString("direccion_rte"));
restaurante.setWeb(obj.getString("web_rte"));
restaurante.setTel_rte(obj.getString("tel_rte"));
restaurante.setTel_reservas(obj.getString("tel_reservas"));
restaurante.setFoto(obj.getString("foto_rte"));
restaurante.setCalificacion(obj.getDouble("calificacion_rte"));
restaurante.setTipo_rte(obj.getString("tipo_rte"));
restaurante.setFacebook(obj.getString("facebook_rte"));
restaurante.setTwitter(obj.getString("google_rte"));
restaurante.setZona(obj.getString("zona_rte"));
restaurante.setCiudad(obj.getInt("ciudad"));
restaurante.setPoi(obj.getInt("poi"));
// adding movie to movies array
restauranteList.add(restaurante);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage(obj.optString("id_rte"));
// pDialog.show();
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Restaurante rteActual = (Restaurante) adapter.getItem(position);
String msg = "Elegiste el restaurante " + rteActual.getNombre();
Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity(), Detalle_Restaurante.class);
intent.putExtra("id_rte", rteActual.getId_rte());
intent.putExtra("nombre_rte", rteActual.getNombre());
intent.putExtra("descripcion_rte", rteActual.getDescripcion());
intent.putExtra("latitud_rte", rteActual.getLatitud());
intent.putExtra("longitud_rte", rteActual.getLongitud());
intent.putExtra("direccion_rte", rteActual.getDireccion());
intent.putExtra("web_rte", rteActual.getWeb());
intent.putExtra("tel_rte", rteActual.getTel_rte());
intent.putExtra("tel_reservas", rteActual.getTel_reservas());
intent.putExtra("foto_rte", rteActual.getFoto());
intent.putExtra("calificacion_rte", rteActual.getCalificacion());
intent.putExtra("tipo_rte", rteActual.getTipo_rte());
intent.putExtra("facebook_rte", rteActual.getFacebook());
intent.putExtra("google_rte", rteActual.getTwitter());
intent.putExtra("zona_rte", rteActual.getZona());
intent.putExtra("ciudad_rte", rteActual.getCiudad());
intent.putExtra("poi_rte", rteActual.getPoi());
startActivity(intent);
}
}
As mentioned in the comment,
Data is being readded to tipoRestauranteList in your onResponse() method so to avoid that write tipoRestauranteList.clear() after hidePDialog().
Same will be happening in your #F12. Doing this you can rectify the same. :)