I'm working on a simple news app.
I need to fetch data from a remote server in JSON format then put it in view. I use TabLayout and recyclerView to display data categories and Volley for the query no API here.
The TabLayout is set automatically depending on data from JSON where I extract tabs title and the content of every tab is being displayed on recyclerView (Article title, image, content, links...) and rendered inside a fragment
I spent several hours trying to debug it without success., but whatever I do, no data is being displayed. Not sure what I'm doing wrong.
I know this is not the right place to ask for such things, but I'm a bit of a desperate and would need some experienced developer than me look at my problem.
How it works:
Activity launches BaseArticleFragment which calls a method that loads contents categories and bind the data to the views:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.fm = getSupportFragmentManager();
this.baseArticleFragment = new BaseArticleFragment();
FragmentTransaction ft = this.fm.beginTransaction();
ft.add(R.id.fragment_container, this.baseArticleFragment, TAB_LAYOUT_FRAGMENT_TAG);
ft.commit();
}
When launched, baseArticleFragment calls loadCategories() method inside its onActivityCreated() method:
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
loadCategories();
}
here is the loadCategories() method:
private void loadCategories(){
String url = "http://somesite.com/categories"; //link to grab the json data
ApplicationController.getInstance().addToRequestQueue(
new JsonObjectRequest(0, url, null, new Listener<JSONObject>() { //0 is the Volley code for GET method
#Override
public void onResponse(JSONObject jsonObject) {
BaseArticleFragment.categories = JSONParser.parseCategories(jsonObject);
BaseArticleFragment.this.mViewPager.setAdapter(
new RecyclerViewFragmentPagerAdapter(BaseArticleFragment.this.getChildFragmentManager(),
BaseArticleFragment.categories));
BaseArticleFragment.this.mTabLayout.setupWithViewPager(BaseArticleFragment.this.mViewPager);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError vError){
Log.d("BaseArticleFragment", "---Volley Error---");
Snackbar.make(BaseArticleFragment.this.mTabLayout, R.string.error_load_categories, Snackbar.LENGTH_SHORT)
.setAction(R.string.action_retry, new View.OnClickListener() {
#Override
public void onClick(View v) {
BaseArticleFragment.this.loadCategories();
}
}).show();
}
}));
}
I guess the problem may be with the query but not sure cause I think my logic here is good
EDIT :
Here is the JSON data I need to fetch:
[
{
"name": "Topic 1",
"tid": "2",
},
{
"name": "Topic 2",
"tid": "3",
},
{
"name": "Topic 3",
"tid": "4",
},
{
"name": "Topic 4",
"tid": "5",
},
{
"name": "Topic 5",
"tid": "6",
},
{
"name": "Topic 6",
"tid": "1415",
},
{
"name": "Topic 7",
"tid": "1414",
},
{
"name": "Topic 8",
"tid": "1298",
},
{
"name": "Topic 9",
"tid": "1301",
},
{
"name": "Topic 10",
"tid": "1299",
},
{
"name": "Topic 11",
"tid": "1302",
},
{
"name": "Topic 12",
"tid": "1300",
},
{
"name": "Topic 13",
"tid": "1297",
}
]
Edit 2:
I forget to paste the code for parseCategories() in my JSONPArser class
public static ArrayList<Category> parseCategories(JSONObject jsonObject) {
ArrayList<Category> categoryArrayList = new ArrayList<>();
try {
JSONArray categories = jsonObject.getJSONArray("categories");
Category all = new Category();
all.setTid("0");
all.setName(ApplicationController.getInstance().getString(R.string.tab_all));
categoryArrayList.add(all);
for (int i = 0; i < categories.length(); i++) {
JSONObject catObject = categories.getJSONObject(i);
Category category = new Category();
category.setTid(catObject.getString("tid"));
category.setName(catObject.getString("name"));
categoryArrayList.add(category);
}
return categoryArrayList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
Try this #esQmo_,
StringRequest stringRequest = new StringRequest(url , new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
ArrayList<Hashmap<String,String>> arraylist = new
ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
HashMap<String, String> hashMap = new HashMap<>();
String name =
jsonArray.getJSONObject(i).getString("name");
String tid =
jsonArray.getJSONObject(i).getString("tid");
hashMap.put("name", name);
hashMap.put("tid ", tid );
arraylist.add(hashMap);
Log.e("response",name + "\n" + tid);
}
attachAdapter(arraylist);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(stringRequest);
//setting adapter data to the RecyclerView
private void attachAdapter(ArrayList<HashMap<String, String>>
arrayList) {
ExampleAdapter adapter = new ExampleAdapter(arrayList,this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
This is the adapter class
public class ExampleAdpater extends RecyclerView.Adapter<ExampleAdpater.ExampleViewHolder>{
public ArrayList<HashMap<String,String>> arraylist;
public Context context;
public ExampleAdpater(ArrayList<HashMap<String, String>> arraylist, Context context) {
this.arraylist= arraylist;
this.context = context;
}
#NonNull
#Override
public ExampleViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textLayout,viewGroup,false);
return new ExampleViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder viewHolder, int i) {
HashMap<String,String> hashMap = arraylist.get(i);
viewHolder.name.setText(hashMap.get("name"));
viewHolder.tid.setText(hashMap.get("tid"));
}
#Override
public int getItemCount() {
return arraylist.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder{
TextView name,tid;
public ExampleViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
tid = itemView.findViewById(R.id.tid);
name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), ""+name.getText().toString(),
Toast.LENGTH_SHORT).show();
}
});
}
}
}
textLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/name"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tid"
/>
</LinearLayout>
You forgot to add this thing at the end of the "load" method:
Volley.newRequestQueue(this).add(jsonRequest);
Try to add it...
Instead of using new RequestQueue, please use RequestQueue jsonQueue = new RequestQueue
Like this:
RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "https://someurl.com/api";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
JSONArray ja = new JSONArray(response);
for(int i = 0; i < ja.length(); i++)
{
JSONObject jo = ja.get(i);
String name = jo.getString("name");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("LOG", error.toString());
}
});
requestQueue.add(jsonObjectRequest);
Just check if you have set LayoutManager for recyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(MyActivity.this));
Can we have your code and JSON data too? Since we can't read what's on your mind or on your computer... Plase make some edits to your post, add code and json data so we may help you.
Since you are getting a timeout error you can change the timeout value so that it will be willing to wait longer.
Try something like this:
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
where MY_SOCKET_TIMEOUT_MS is amount of time (in milliseconds) you want to wait before a timeout. Start with 5000 (5 seconds) and play around with it.
Do this before
requestQueue.add(jsonObjectRequest);
Related
I have an issue that i unable to understand i.e when i make an http request i get following JSONObject as response. I have to loop-iterate every keys, take the data that i need, build them in an object and fill the spinner, but i think there is something wrong in the loop or i don't know, cause when i take every object, alone without a loop, all work fine,
when i loop to build object and add to array list dynamically it don't work:
{
"Conteggio": 2,
"0": {
"Distributore Information": {
"id_distributore": "1",
"NomeDistributore": "Colonnina 0",
"litriiniziocolonna": "444",
}
},
"1": {
"Distributore Information": {
"id_distributore": "2",
"NomeDistributore": "Colonnina 1",
"litriiniziocolonna": "555",
}
}
}
I know that it's wrong loop through a JSONObject but i cant change this JSON.
Here the android code code:
private void getInfoColonnina(){
String url = "https://icantshowtheurlbutitworkfine_module.json";
final SharedPreferences myPref = getSharedPreferences("loginPref", MODE_PRIVATE);
final SharedPreferences.Editor myPreff = myPref.edit();
RequestQueue requestQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
List<DistrBean> distrBeansList = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
Iterator keys = jsonObject.keys();
while (keys.hasNext()) {
Object key = keys.next();
JSONObject value = jsonObject.getJSONObject((String) key);
JSONObject info = value.getJSONObject("Distributore Information");
String LitriColonnina1 = info.getString("litriiniziocolonna");
String NomeDistributore1 = info.getString("NomeDistributore");
String id_distributore1 = info.getString("id_distributore");
DistrBean distrBean = new DistrBean();
distrBean.setLitriColonnina(LitriColonnina1);
distrBean.setNomeDistributore(NomeDistributore1);
distrBean.setIdDistributore(id_distributore1);
distrBeansList.add(distrBean);
}
ArrayAdapter<DistrBean> adapter = new ArrayAdapter<DistrBean>(InizioTurnoActivity.this, android.R.layout.simple_spinner_item, distrBeansList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
DistrBean distrBean = (DistrBean) adapterView.getSelectedItem();
getSelectedDistr(distrBean);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Toast.makeText(InizioTurnoActivity.this, "CHIAMATA INFOCOLONNINA FALLITA", Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(stringRequest);
}
public void getSelectedDistr(DistrBean v){
DistrBean distrBean = (DistrBean) spinner.getSelectedItem();
setDistrData(distrBean);
}
private void setDistrData(DistrBean distrBean){
String name = distrBean.getNomeDistributore();
String litri = distrBean.getLitriColonnina();
String id = distrBean.getIdDistributore();
tvProgressivo.setText(litri);
tvColonnina.setText(name);
Toast.makeText(this, "Hai selezionato " + name + "che ha litri: " + litri, Toast.LENGTH_LONG).show();
}
}
Can you guys help me? thank you in advance!
your json is not valid
{
"Conteggio": 2,
"0": {
"Distributore Information": {
"id_distributore": "1",
"NomeDistributore": "Colonnina 0",
"litriiniziocolonna": "444", //this line
}
},
"1": {
"Distributore Information": {
"id_distributore": "2",
"NomeDistributore": "Colonnina 1",
"litriiniziocolonna": "555", //this line
}
}
}
You should test your rest api on postman before integrating it in android app and use Gson library, response model to handle all json response. Gson library automatically parse data according to your model so you dont need to get data by specifying individual key.
I think that your parsing algorithm has issue.
Iterator keys = jsonObject.keys();
-> Conteggio, 0, 1
So you should skip one.
I am getting country name from spinner , now i want to set country code according to spinner item in edittext ...but i dont to know how to set according to spinner item ...
this is code (here i am getting country name from spinner):
pmmobile = (EditText) findViewById(R.id.mob);
private void getCountryData(){
StringRequest stringRequest = new StringRequest(DATA_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
Log.d("Test",response);
JSONArray result = new JSONArray(response);
//Calling method getCountry to get the Country from the JSON Array
getCountry(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}});
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
private void getCountry(JSONArray jsonArrayCountry){
//Traversing through all the items in the json array
List<Country> countries = new ArrayList<>();
try {
String country_name, country_code;
JSONObject countries_object;
for (int i = 0; i < jsonArrayCountry.length(); i++) {
countries_object = jsonArrayCountry.getJSONObject(i);
country_code = countries_object.getString("id");
country_name = countries_object.getString("Name");
countries.add(new Country(country_code, country_name));
}
ArrayAdapter countryAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, countries);
pmcountry.setPrompt("Select Country");
pmcountry.setAdapter(countryAdapter);
pmcountry.setAdapter(new NothingSelectedSpinnerAdapter(countryAdapter,
R.layout.contact_spinner_row_nothing_selected,this));
pmcountry.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
} catch (JSONException e) {
Log.e("PMSearchActivity", e.getLocalizedMessage(), e);
}
}
i want to set country code in pmmobile..kindly help, new to android.
this is my json:
[
{
"id": "1",
"Name": "Afghanistan",
"CountryCode": "AF",
"CountryIso": "AFG"
},
{
"id": "2",
"Name": "Albania",
"CountryCode": "AL",
"CountryIso": "ALB"
},
I suppose that if you want to display a String you are going to use a TextView, not an EditText.
Anyway:
pmmobile.setText(<... string or string res ID ...>);
Simple as that.
To keep it asynchronous I suppose that you should put this inside one of your listeners, for example onItemSelected().
Update.
Being not aware of what you are trying to do, I suggest you anyway to browse the constants inside the Locale utility class. You can get all the language ISO codes and what you need from handy constants and utilities from there, without getting crazy with json and similar stuff.
Locale.COUNTRY.getLanguage();
or
Locale.getISOLanguages();
Although I don't know if this is what you need.
I am trying to parse json with volley and display with recycler-card view in my tabbed fragment class in android. The json response is not displayed in the fragment. No errors or exceptions are shown. The app runs fine but no data is displayed. Take a look at the code below and tell me where I went wrong.
My Fragment Class
public class Latest_News extends Fragment {
private RecyclerView recyclerView;
private List<NewsItems> newsItemsList = new ArrayList<>();
private static final String TAG = Latest_News.class.getSimpleName();
private NewsItems newsItems;
public Latest_News() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
networkAvailable();
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View mView = inflater.inflate(R.layout.fragment_latest__news, container, false);
recyclerView = (RecyclerView) mView.findViewById(R.id.latestNews_recyclerView);
recyclerView.setHasFixedSize(true);
LinearLayoutManager llMan = new LinearLayoutManager(getContext());
llMan.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(llMan);
//recyclerView.setAdapter(new HomeFrag_RecyclerAdapter(getActivity(), newsItemsList));
if (networkAvailable()){
String url = "www.goal.com/api"; // fake url, pls dont mind
RequestQueue mRequestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject newsObject = new JSONObject(response.toString());
String title = newsObject.getString("title");
String time = newsObject.getString("time");
String date = newsObject.getString("date");
String link = newsObject.getString("link");
String content = newsObject.getString("content");
String image = newsObject.getString("image" + "");
newsItems = new NewsItems();
newsItems.setImage_Id(Integer.parseInt(image));
newsItems.setNewsDate(date);
newsItems.setNewTitle(title);
newsItems.setNewsDesc(content);
newsItems.setNewsUrl(link);
newsItems.setNewsTime(time);
newsItemsList.add(newsItems);
} catch (JSONException e) {
e.printStackTrace();
}
recyclerView.setAdapter(new HomeFrag_RecyclerAdapter(getActivity(), newsItemsList));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG,"Error is: " + error.toString());
}
});
mRequestQueue.add(jsonObjectRequest);
}
else{
Toast.makeText(getActivity(), "Turn On Mobile Data or Wifi", Toast.LENGTH_SHORT).show();
}
return mView;
}
private boolean networkAvailable() {
ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()){
isAvailable = true;
}
return isAvailable;
}
}
Fragment Adapter Code is Shown Below:
public class HomeFrag_RecyclerAdapter extends RecyclerView.Adapter<HomeFrag_RecyclerAdapter.MyHolder> {
private Context context;
List<NewsItems> newsItemsList;
public HomeFrag_RecyclerAdapter(Context context, List<NewsItems> newsItemsList) {
this.context = context;
this.newsItemsList = newsItemsList;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.tab_frags_customview,parent,false);
return new MyHolder(v);
}
#Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.title.setText(newsItemsList.get(position).getNewTitle());
holder.descn.setText(newsItemsList.get(position).getNewsDesc());
holder.time.setText(newsItemsList.get(position).getNewsTime());
holder.date.setText(newsItemsList.get(position).getNewsDate());
int i = position;
Picasso.with(context).load(newsItemsList.get(i).getImage_Id())
.centerCrop()
.error(R.drawable.ic_toc_black_24dp)
.into(holder.coverImg);
}
#Override
public int getItemCount() {
return newsItemsList.size();
}
public class MyHolder extends RecyclerView.ViewHolder{
private TextView title, descn, time, date;
private ImageView coverImg;
public MyHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.news_titleTxt);
descn = (TextView) itemView.findViewById(R.id.news_DescTxt);
time = (TextView) itemView.findViewById(R.id.news_TimeTxt);
date = (TextView) itemView.findViewById(R.id.newsDateTxt);
coverImg = (ImageView) itemView.findViewById(R.id.newsImage);
}
}
}
Sample JSON to be parsed
<pre>
{
"0": {
"image": null,
"title": "Suresh Raina to miss 2nd ODI against New Zealand ",
"time": "08:29 pm ",
"date": "18 Oct ",
"content": "Indian cricketer Suresh Raina will miss the second ODI against New Zealand at Delhi on Thursday. ...",
"link": "https://full-story.newsinshorts.com/v1/article/a659a7be-0c4d-408c-851d-689da6b95498-1 "
},
"1": {
"image": null,
"title": "Harley-Davidson net income falls by 18.67% to $114 mn ",
"time": "08:29 pm ",
"date": "18 Oct ",
"content": "Motorcycle manufacturer Harley-Davidson on Tuesday reported an 18.67% year-on-year decline in net ...",
"link": "https://full-story.newsinshorts.com/v1/article/448cc170-1d42-4109-9c50-0fe3a3c36f44-1 "
},
"2": {
"image": null,
"title": "JNU to get 200 solar power operated street lights ",
"time": "08:27 pm ",
"date": "18 Oct ",
"content": "The Jawaharlal Nehru University in Delhi is set to get 200 solar power operated street lights, Vice ...",
"link": "https://full-story.newsinshorts.com/v1/article/96db26c8-be8f-4313-8d51-27fee9bd084d-1 "
},
"3": {
"image": null,
"title": "Patiala Court dismisses fake degree case against Irani ",
"time": "08:22 pm ",
"date": "18 Oct ",
"content": "Patiala House Court today dismissed a case against Union Minister Smriti Irani for allegedly ...",
"link": null
},
</pre>
XML layout for the Fragment Class above:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.joey.mydrawerapp.Fragments.HomeFragment_Fragments.Latest_News">
<!-- TODO: Update blank fragment layout -->
<include layout="#layout/recyclerview_layout"
android:id="#+id/latestNews_recyclerView"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="30sp"
android:gravity="center"
android:textStyle="bold"
android:text="Stay Tuned For Latest News" />
</RelativeLayout>
I generally don't parse JSON by hand anymore, I always use Gson or jackson. Provided your json is correct, your onResponse can look something like this:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response)
#Override
public void onResponse(Stringresponse) {
Gson gson = new Gson();
Map<String,Item> map = gson.fromJson(response, new TypeToken<Map<String,Item>>(){}.getType());
newsItemLists = new ArrayList(); // Clear the list if desired
for (Item item : map.values()) {
newsItems = new NewsItems();
// Copy all item attributes to newsItems here.
// if NewsItems is annotated correct, it can even be used to parse
// the json instead of the Item class below.
newsItemsList.add(newsItems);
}
// Move this line into the onCreate() initializng the adapter with an empty list.
//recyclerView.setAdapter(new HomeFrag_RecyclerAdapter(getActivity(), newsItemsList));
// add this to notify the adapter that the list has changed.
adapter.notifyDataSetChanged();
}
You will need a pojo for the gson object:
class Item {
String image;
String title;
String time;
String date;
String content;
String link;
}
Update
I've updated my answer just a bit to make a StringRequest Volley instead of a JSONRequest. We'll use the whole string response and parse it as JSON. Alternatively, you can change your Volley JsonObjectRequest to a JsonArrayRequest and receive a JSON array. Then you'll loop over each item in the array and parse it out.
This is my json responce :-
{
"ReplyCode": 1,
"Message": "Franchisee and Plans List",
"data2": [
{
"StateId": 1,
"StateName": "Andaman and Nicobar Island",
"CountryId": 1
},
{
"StateId": 2,
"StateName": "Andhra Pradesh",
"CountryId": 1
},
{
"StateId": 3,
"StateName": "Arunachal Pradesh",
"CountryId": 1
},
{
"StateId": 4,
"StateName": "Assam",
"CountryId": 1
},
This is my method by which i am fetching data from the json :-
public void volleyStatedata() {
if (mGeneralUtilities.isConnected()) {
mProgressDialog.show();
StringRequest stateRequest = new StringRequest(Request.Method.POST, GlobalData.REGISTER_DATA_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mProgressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("data2");
for (int i = 0; i < jsonArray.length(); i++) {
PojoState pojoState = new PojoState();
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
String stateId = jsonObject1.getString("StateId");
String stateName = jsonObject1.getString("StateName");
mStateList.add(stateName);
mStateIdList.add(stateId);
pojoState.setmStateId(stateId);
pojoState.setmStatename(stateName);
mpojoStateList.add(pojoState);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("error", "" + volleyError.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
return params;
}
};
RequestQueue stateQueue = Volley.newRequestQueue(getContext());
stateQueue.add(stateRequest);
} else {
mGeneralUtilities.showAlertDialog("Hey User !", "Please connect to the internet", "Ok");
}
}
This is my Adapter where i am setting it to the autocompletetextview :-
ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, mStateList);
mActState.setAdapter(mAdapter);
mActState.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
mpojoStateList.get(i).getmStateId();
}
});
My problem is autocompletetextview always return id 1.i am applying onitemclick listner on it.but it is getting id 1 always.i want to id accordingly to the state as per shown my json.Can anyone tell me how can I achieve this ??
Your code uses i that returns in the onItemClick callback, which refers to the item you clicked from the visible items in the auto-complete list, not your original list. When you click on the first item in the auto-complete list, i=0, which means it always returns the "Andaman and Nicobar Island" item whose StateId=1.
Off the top of my head, you can get the item String from the mAdapter and compare it to your mpojoStateList and find the corresponding item. (Check the sample code)
final ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, mStateList);
mActState.setAdapter(mAdapter);
mActState.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String itemName = mAdapter.getItem(i);
for (PojoState pojo : mpojoStateList) {
if (pojo.mStateName.equals(itemName)) {
String id = pojo.getmStateId(); // This is the correct ID
break; // No need to keep looping once you found it.
}
}
}
});
It also is better if, inside your PojoState object, you override your toString() method and make it return the mStateName, and pass the mpojoStateList to the adapter without having to make 3 ArrayLists. That way, mAdapter.getItem(i) will return a PojoState object instead of a String, and you can use its ID without referring to the returned position (i).
I m creating dynamic tabs in android in which the data for the tabs is populated from the json
Following is the json response
{
"shop_details": [
{
"id": "36",
"shop_name": "All in One Mart",
"shop_no": "23223",
"shop_address": "Tinkune",
"phone": "9804966595",
"email": "arjundangal4#gmail.com",
"user_name": "arjun",
"address": "",
"tel": "",
"fax": "",
"facebook": "",
"twitter": "",
"googleplus": "",
"image": "",
"featured_image": ""
}
],
"category": [
{
"category_id": "35",
"category_name": "Skirt",
"product": [
{
"product_id": "49",
"product_name": "Skirt",
"category_id": "35",
"subcategory_id": "37",
"product_color": "blue",
"description": "Skirt for girls",
"price": "301",
"discount": "0",
"service_charge": "0",
"user_id": "36",
"image_name": "6baab8a5308b7e821f5b6387794979a4.jpeg",
"created_at": "2016-07-04 03:54:54"
}
]
},
{
"category_id": "36",
"category_name": "Men",
"product": [
{
"product_id": "48",
"product_name": "Glasses",
"category_id": "36",
"subcategory_id": "39",
"product_color": "red",
"description": "Glasses of Rayban",
"price": "594",
"discount": "23",
"service_charge": "22",
"user_id": "36",
"image_name": "fce01420a9021fdb159226b4bdc5b591.jpg",
"created_at": "2016-07-04 03:52:58"
}
]
},
{
"category_id": "37",
"category_name": "Bags",
"product": [
{
"product_id": "50",
"product_name": "Laptop bag",
"category_id": "37",
"subcategory_id": "41",
"product_color": "black",
"description": "Bag to carry laptop",
"price": "190",
"discount": "2",
"service_charge": "3",
"user_id": "36",
"image_name": "e836e090a54cd2b6b594fa0a3382bb38.jpg",
"created_at": "2016-07-04 04:14:08"
}
]
}
]
}
Following is the code to fetch in which i add the tabs dynamically
private void getShopDetails() {
coordinatorLayout.setVisibility(View.GONE);
new ProgressDialog(this);
ProgressDialog.show();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(shopDetailsJsonUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
ProgressDialog.dismiss();
coordinatorLayout.setVisibility(View.VISIBLE);
try {
JSONArray shopDetailsArray = response.getJSONArray("shop_details");
JSONObject shopDetailsObj = shopDetailsArray.getJSONObject(0);
shopName = shopDetailsObj.getString("shop_name");
phone = shopDetailsObj.getString("tel");
shopNum = shopDetailsObj.getString("shop_no");
shopAddress = shopDetailsObj.getString("shop_address");
shopImage = shopDetailsObj.getString("featured_image");
Glide.with(getApplicationContext()).load("http://allmartapp.com/appapi/uploads/" + shopImage).diskCacheStrategy(DiskCacheStrategy.SOURCE).into(backdrop);
colLayout.setTitle(shopName);
address.setText("Address - Shop no -" + shopNum + ", " + shopAddress);
JSONArray tabsArray = response.getJSONArray("category");
categoryId = new int[tabsArray.length()];
for (int i = 0; i < tabsArray.length(); i++) {
JSONObject tabsObj = tabsArray.getJSONObject(i);
tabLayout.addTab(tabLayout.newTab().setText(tabsObj.getString("category_name")));
categoryId[i] = tabsObj.getInt("category_id");
}
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
pager.setAdapter(pagerAdapter);
pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
ShopDetailsTabsFragment.sgetid(categoryId[tab.getPosition()]);
Log.d("CATIID", categoryId[tab.getPosition()] + "");
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
ProgressDialog.dismissWithError();
}
});
int socketTimeout = 30000;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
jsonObjectRequest.setRetryPolicy(policy);
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
}
In ontabselected() i assigned the category id according to the position of the tabs and call the sgetid() function which is in the fragment
My pageradapter returns only one Fragment with the recyclerview.
Following is the Fragment code
public class ShopDetailsTabsFragment extends Fragment {
RecyclerView recyclerView;
boolean isViewShown = false;
CategoryListItemsAdapter shopListRvAdapters;
private String shopDetailsJsonUrl = "http://allmartapp.com/appapi/json/get_shop_details_by_shop_id/";
private String baseshopDetailsJsonUrl = "http://allmartapp.com/appapi/json/get_shop_details_by_shop_id/";
ArrayList<CategoryItemsListModel> arrayList = new ArrayList<>();
static int catid = 0;
int shopId;
public ShopDetailsTabsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_shop_details_tabs, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.rv);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
SharedPreferences sharedPreferences = getActivity().getSharedPreferences("SHOPID", Context.MODE_PRIVATE);
shopId = sharedPreferences.getInt("shopid", 0);
return v;
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getView() != null) {
isViewShown = true;
getShopCat();
// fetchdata() contains logic to show data when page is selected mostly asynctask to fill the data
} else {
isViewShown = false;
}
}
public static void sgetid(int cat) {
catid = cat;
}
private void getShopCat() {
recyclerView.setAdapter(null);
shopDetailsJsonUrl += shopId;
arrayList.clear();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(shopDetailsJsonUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("JSON", response.toString());
try {
JSONArray categoryArray = response.getJSONArray("category");
for (int i = 0; i < categoryArray.length(); i++) {
JSONObject catObj = categoryArray.getJSONObject(i);
int category_id = catObj.getInt("category_id");
if (category_id == catid) {
JSONArray productArray = catObj.getJSONArray("product");
for (int j = 0; j < productArray.length(); j++) {
JSONObject productObj = productArray.getJSONObject(j);
String name = productObj.getString("product_name");
String image = productObj.getString("image_name");
int id = productObj.getInt("product_id");
int price = productObj.getInt("product_id");
CategoryItemsListModel shopListRvModels = new CategoryItemsListModel(id, image, name, price);
arrayList.add(shopListRvModels);
shopListRvAdapters = new CategoryListItemsAdapter(arrayList, getActivity());
recyclerView.setAdapter(shopListRvAdapters);
shopListRvAdapters.notifyDataSetChanged();
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
int socketTimeout = 30000;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
jsonObjectRequest.setRetryPolicy(policy);
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
shopDetailsJsonUrl = baseshopDetailsJsonUrl;
}
}
My problem is that, the tabs are showing strange behaviors. I know that the logic to fetch the category lists is correct. But I think there is problem in the state of the fragment. When i switch the tabs, the data loaded in the tabs are sometimes duplicated and even the data are loaded twice sometimes. Any suggestions are appreciated as im facing the problem for couple of days. I want to know the easy way to load the data in the tabs.
Try below code if it helps:
public class ShopDetailsTabsFragment extends Fragment {
RecyclerView recyclerView;
boolean isViewShown = false;
CategoryListItemsAdapter shopListRvAdapters;
private String shopDetailsJsonUrl = "http://allmartapp.com/appapi/json/get_shop_details_by_shop_id/";
private String baseshopDetailsJsonUrl = "http://allmartapp.com/appapi/json/get_shop_details_by_shop_id/";
ArrayList<CategoryItemsListModel> arrayList = new ArrayList<>();
static int catid = 0;
int shopId;
public ShopDetailsTabsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_shop_details_tabs, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.rv);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
SharedPreferences sharedPreferences = getActivity().getSharedPreferences("SHOPID", Context.MODE_PRIVATE);
shopId = sharedPreferences.getInt("shopid", 0);
shopListRvAdapters = new CategoryListItemsAdapter(arrayList, getActivity());
recyclerView.setAdapter(shopListRvAdapters);
return v;
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getView() != null) {
isViewShown = true;
getShopCat();
// fetchdata() contains logic to show data when page is selected mostly asynctask to fill the data
} else {
isViewShown = false;
}
}
public static void sgetid(int cat) {
catid = cat;
}
private void getShopCat() {
recyclerView.setAdapter(null);
shopDetailsJsonUrl += shopId;
arrayList.clear();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(shopDetailsJsonUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("JSON", response.toString());
try {
JSONArray categoryArray = response.getJSONArray("category");
if(arrayList!=null){
if(arrayList.size()>0)
arrayList.clear();
}
for (int i = 0; i < categoryArray.length(); i++) {
JSONObject catObj = categoryArray.getJSONObject(i);
int category_id = catObj.getInt("category_id");
if (category_id == catid) {
JSONArray productArray = catObj.getJSONArray("product");
for (int j = 0; j < productArray.length(); j++) {
JSONObject productObj = productArray.getJSONObject(j);
String name = productObj.getString("product_name");
String image = productObj.getString("image_name");
int id = productObj.getInt("product_id");
int price = productObj.getInt("product_id");
arrayList.add(new CategoryItemsListModel(id, image, name, price));
}
shopListRvAdapters.notifyDataSetChanged();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
int socketTimeout = 30000;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
jsonObjectRequest.setRetryPolicy(policy);
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
shopDetailsJsonUrl = baseshopDetailsJsonUrl;
}