Error in Adding data into Recycleview which are fetched from server - android

I am trying to get strings(usernames) from Server wanna put it into Recycle.For that, I am using JSON to fetch data and Asynctask to generate a new thread.I successfully getting usernames from the server but failed to put them in recycleview.
This is my Mainactivity.java
public class MainActivity extends AppCompatActivity {
BufferedReader reader;
private String content;
RecyclerView recyclerView;
Adapter madapter;
List<String> data = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ApiAsyncTask().execute();
}
private class ApiAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
getData();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
recyclerView=(RecyclerView)findViewById(R.id.rv123);
recyclerView.setLayoutManager(new LinearLayoutManager());
data.add("name");
Dataadapter madapter = new Dataadapter(data);
recyclerView.setAdapter(madapter);
}
}
private void getData(){
try {
URL url = new URL("https://jsonplaceholder.typicode.com/comments");
URLConnection conn = url.openConnection();
conn.setDoOutput(false);
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + " ");
}
// Append Server Response To Content String
content = sb.toString();
Log.e("TAG", "Response is -> " + content);
JSONArray jsonArray = new JSONArray(content);
for(int i=0;i<=4;i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
String name = jsonObject.getString("name");
Log.e("TAG", "Username is -> " + name);}
}
catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
This is my Adapter
public class Dataadapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public TextView textView;
private List<String> data;
public Dataadapter(List<String> data) {
this.data = data;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv);
}}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View dataView = layoutInflater.inflate(R.layout.container, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(dataView);
return myViewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
textView.setText(data.get(position));
}
#Override
public int getItemCount() {
return data.size();
}
}
Using 2 XML files.One is Mainactivity.xml and other is Container.xml.Please help me on how to show usernames (which I fetched from the server)into recycleview.For now, when I run the app, it just showing the layout only.Not getting any username in that layout.But in my log, I can see the usernames.Thank u

Just add the objects to your list
for(int i=0;i<=4;i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
data.add(jsonObject.getString("name"));
}
And the LinearLayoutManager constructor takes one parameter, a Context.
In your onPostExecute, do this -
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

Try this code, I tested it and it's working.
Here's MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
BufferedReader reader;
RecyclerView recyclerView;
Dataadapter madapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.rv123);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
madapter = new Dataadapter();
recyclerView.setAdapter(madapter);
new ApiAsyncTask().execute();
}
private class ApiAsyncTask extends AsyncTask<Void, Void, List<String>> {
#Override
protected List<String> doInBackground(Void... voids) {
return getData();
}
#Override
protected void onPostExecute(List<String> names) {
madapter.updateData(names);
}
}
private List<String> getData() {
List<String> data = new ArrayList<>();
try {
URL url = new URL("https://jsonplaceholder.typicode.com/comments");
URLConnection conn = url.openConnection();
conn.setDoOutput(false);
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
// Append server response in string
sb.append(line);
}
// Append Server Response To Content String
String content = sb.toString();
Log.e("TAG", "Response is -> " + content);
JSONArray jsonArray = new JSONArray(content);
for (int i = 0; i < 50; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String name = jsonObject.getString("name");
Log.e("TAG", "Username is -> " + name);
data.add(name);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
Log.d(TAG, "getData: " + data.size());
return data;
}
}
and here's Dataadapter.java
public class Dataadapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public TextView textView;
private List<String> data;
public Dataadapter() {
data = new ArrayList<>();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View dataView = layoutInflater.inflate(R.layout.container, parent, false);
return new MyViewHolder(dataView);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
textView.setText(data.get(position));
}
#Override
public int getItemCount() {
return data.size();
}
public void updateData(List<String> data) {
this.data = data;
notifyDataSetChanged();
}
}
The data returned from the API endpoint contains 500 items, I used 50 instead to load faster.

You should not make holder's textView as adapter's local variable and assign value on holder's constructor. Since ViewHolder may be reused and parsed to Adapter.onBindViewHolder() and then the textView used in onBindViewHolder() method is not the textView in holder( the ViewHolder constructor not called). You can make textView as MyViewHolder's variable and use holder.getTextView().setText(item) to set text.

Related

Fragment, Volley and RecyclerView

I hope someone out there can help me solve my problem. I have android app that have 3 tabs, i use fragment, first tab is recyclerView list, second tabs is map. the problem is in tabs 1, i need to fetch data with volley to recyclerView on tabs 1, if run fine but i cannot see the data on first app start, but when i change tab and back to tab 1 again it will refresh the data and show the data on recyclerView.
Adapter.java
public class CustomListAdapterWarkop extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Warkop> mWarkop;
private LayoutInflater inflater;
public CustomListAdapterWarkop(Context context, List<Warkop> mWarkop) {
this.context=context;
inflater= LayoutInflater.from(context);
this.mWarkop = mWarkop;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_warkop_row, parent, false);
ItemViewHolder holder = new ItemViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ItemViewHolder viewHolder = (ItemViewHolder) holder;
Warkop current = mWarkop.get(position);
viewHolder.tvNamaWarkop.setText(current.getNamaWarkop());
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.noimage)
.showImageOnFail(R.drawable.noimage)
.showImageOnLoading(R.drawable.noimage).build();
imageLoader.displayImage(current.getFotoWarkop(), viewHolder.ivFotoWarkop, options);
}
#Override
public int getItemCount() {
return mWarkop.size();
}
}
ItemHolder.java
package com.andylah.warkopedia;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Created by andylah on 11/3/2017.
*/
public class ItemViewHolder extends RecyclerView.ViewHolder {
public ImageView ivFotoWarkop;
public TextView tvNamaWarkop;
public ItemViewHolder(View itemView) {
super(itemView);
tvNamaWarkop = itemView.findViewById(R.id.nama_warkop);
ivFotoWarkop = itemView.findViewById(R.id.image_warkop);
}
}
Tab 1.java
public class tabSatu extends Fragment {
private static final String TAG = tabDua.class.getSimpleName();
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private boolean isFragmentLoaded = false;
View vTabSatu;
private RecyclerView recyclerView;
public static List<Warkop> warkopList = new ArrayList<Warkop>();
private CustomListAdapterWarkop warkopAdapter;
public tabSatu(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
new AsyncFetch().execute();
vTabSatu = inflater.inflate(R.layout.tabsatu_view, container, false);
recyclerView = vTabSatu.findViewById(R.id.warkop_container);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
Log.d("LOG : ", "onCreatedView Run");
// Inflate the layout for this fragment
return vTabSatu;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
warkopAdapter = new CustomListAdapterWarkop(getActivity(), warkopList);
warkopAdapter.notifyDataSetChanged();
recyclerView.setAdapter(warkopAdapter);
Log.d("LOG : ", "onViewCreated Run");
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !isFragmentLoaded ) {
// Load your data here or do network operations here
isFragmentLoaded = true;
//new AsyncFetch().execute();
}else{
isFragmentLoaded = false;
Log.d("LOG : ", "isFragmentLoaded = false");
}
}
private class AsyncFetch extends AsyncTask<String, String, String> {
ProgressDialog pDialog = new ProgressDialog(getActivity());
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.setMessage("Loading list warkop ...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... strings) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL(AppConfig.LOAD_WARKOP);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
try{
JSONObject object = new JSONObject(result);
String getObject = object.getString("warkop");
JSONArray jsonArray = new JSONArray(getObject);
boolean error = object.getBoolean("error");
if(!error){
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Warkop warkop = new Warkop();
warkop.setNamaWarkop(jsonObject.getString("nama_warkop"));
warkop.setAlamatWrkop(jsonObject.getString("alamat_warkop"));
warkop.setKotaWarkop(jsonObject.getString("kota_warkop"));
warkop.setLatWarkop(Double.parseDouble(jsonObject.getString("lat_warkop")));
warkop.setLangWarkop(Double.parseDouble(jsonObject.getString("long_warkop")));
warkop.setIsWifi(Integer.parseInt(jsonObject.getString("is_wifi")));
warkop.setIsToilet(Integer.parseInt(jsonObject.getString("is_toilet")));
warkop.setIsTv(Integer.parseInt(jsonObject.getString("is_tv")));
warkop.setIsColokan(Integer.parseInt(jsonObject.getString("is_colokan")));
warkop.setIsParkir(Integer.parseInt(jsonObject.getString("is_parkir")));
warkop.setFotoWarkop(jsonObject.getString("foto_warkop"));
warkopList.add(warkop);
}
}else{
String errorMsg = object.getString("error_msg");
Toast.makeText(getContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
}catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
}
Problem: Even you call notifyDataSetChanged() but there are no data in Adapter.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
warkopAdapter = new CustomListAdapterWarkop(getActivity(), warkopList);
warkopAdapter.notifyDataSetChanged();
recyclerView.setAdapter(warkopAdapter);
}
So you need to set and notify warkopList to Adapter after API call. It will help you.
tabSatu:
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
try {
JSONObject object = new JSONObject(result);
String getObject = object.getString("warkop");
JSONArray jsonArray = new JSONArray(getObject);
boolean error = object.getBoolean("error");
if (!error) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Warkop warkop = new Warkop();
...
warkopList.add(warkop);
adapter.setItems(warkopList);
}
}
...
}
CustomListAdapterWarkop: add setItem() method to Adapter
public class CustomListAdapterWarkop extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...
public void setItems(List<WarkopList> warkopList) {
mWarkop = warkopList;
notifyDataSetChanged();
}
...
}

Retrieve JSON recycler image gallery data and display in manner like instagram - click image gallery open in Recyclerview with image name

I want to retrieve json recycler image gallery data and display in RecyclerView manner, anyone help me
like Instagram click image gallery open in RecyclerView with image name
Currently I am displaying in a grid manner I don't no how to pass from this recycler to another recycler :
ProfilActivity:
public class ProfilActivity extends AppCompatActivity {
private RecyclerView recyclerView;
ArtistAdapterGallary artistAdapterGallary;
ArrayList < DataArtist > data = new ArrayList < > (); //its in progress dialog arraylist to retrieve array data
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profil);
new AsyncFetch().execute();
}
private class AsyncFetch extends AsyncTask < String, String, String > {
ProgressDialog pdLoading = new ProgressDialog(ProfilActivity.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String...params) {
try {
url = new URL("http://exxxxxxxxxxxxxx");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
DataArtist artistPic = new DataArtist();
artistPic.artistName = json_data.getString("name");
artistPic.artistImage = json_data.getString("profile_image");
data.add(artistPic);
}
// Setup and Handover data to recyclerview
recyclerView = (RecyclerView) findViewById(R.id.profileGride);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 3);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
artistAdapterGallary = new ArtistAdapterGallary(ProfilActivity.this, data);
// recyclerView.setLayoutManager(new LinearLayoutManager(ProfileGrideActivity.this));
recyclerView.setAdapter(artistAdapterGallary);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Custom Adatpter
public class ArtistAdapterGallary extends RecyclerView.Adapter < ArtistAdapterGallary.MyViewHolder > {
private Context context;
private LayoutInflater inflater;
List < DataArtist > data = new ArrayList < > ();
public ArtistAdapterGallary(ProfilActivity context, List < DataArtist > data1) {
this.context = context;
this.data = data1;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.gallary_layout, parent, false);
return new ArtistAdapterGallary.MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ArtistAdapterGallary.MyViewHolder holder, int position) {
final DataArtist current = data.get(position);
holder.artistname.setText(current.artistName);
Glide.with(context).load(data.get(position).getArtistImage()).into(holder.artistImage);
holder.artistImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, Main2Activity.class);
intent.putExtra("link", current.getArtistImage());
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return data.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView artistImage;
TextView artistname;
private View view;
public MyViewHolder(View itemView) {
super(itemView);
artistImage = (ImageView) itemView.findViewById(R.id.imageGride);
artistname = (TextView) itemView.findViewById(R.id.artistName);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(context, Main2Activity.class);
DataArtist artistData = (DataArtist) view.getTag();
String strUrl = artistData.getArtistImage();
String product1 = artistData.getArtistName();
intent.putExtra("ARTIST_IMG", strUrl);
intent.putExtra("ARTIST_NAME", product1);
// intent.putExtra("Your string key",product1);
context.startActivity(intent);
}
}
}
DataArtist :
public class DataArtist {
public String artistImage;
public String artistName;
public String artistId;
private boolean isSelected = false;
public DataArtist() {
this.artistImage = artistImage;
this.artistName = artistName;
}
public String getArtistId() {
return artistId;
}
public void setArtistId(String artistId) {
this.artistId = artistId;
}
public String getArtistImage() {
return artistImage;
}
public void setArtistImage(String artistImage) {
this.artistImage = artistImage;
}
public void setArtistName(String artistName) {
this.artistName = artistName;
}
public String getArtistName() {
return artistName;
}
public void setSelected(boolean selected) {
boolean isSelected = selected;
}
public boolean isSelected() {
return isSelected;
}
}
and I want to know how I can call this data into another recycler

Android - Display data from Adapter in Listview

I've currently got an application that pulls data from a mysql database and displays it in raw JSON format. I'm currently working on pushing this data into a String variable and displaying it on a Listview on a specific activity.
Problem is, when trying to display this data, my Listview is not populating; I'm sure the variable is not empty as the if statement would have captured this.
Here is snippet of MainActivity code:
//Methods to grab information from abhandym_DB database
public void getJSON(View view){
new BackgroundTask().execute();
}
public void parseJSON(View view){
if(JSON_String==null){
Toast.makeText(getApplicationContext(), "First Get Json", Toast.LENGTH_LONG).show();
}else{
Intent intent = new Intent(this,Test.class);
intent.putExtra("JSON_Data",JSON_String);
startActivity(intent);
}
}
class BackgroundTask extends AsyncTask<Void,Void,String>{
String json_url;
#Override
protected void onPreExecute() {
json_url = "http://abhandyman.x10host.com/json_get_data.php";
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(json_url);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream inputSteam = httpURLConnection.getInputStream();
BufferedReader buffereredReader = new BufferedReader(new InputStreamReader(inputSteam));
StringBuilder stringBuilder = new StringBuilder();
while((JSON_String = buffereredReader.readLine())!=null){
stringBuilder.append(JSON_String+"\n");
}
buffereredReader.close();
inputSteam.close();
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
TextView textView = (TextView)findViewById(R.id.fragment1_textview_JSONAPPEAR);
textView.setText(result);
JSON_String = result;
}
}
Here is the code for my Test.java
public class Test extends AppCompatActivity {
String JSON_String;
JSONObject jsonObject;
JSONArray jsonArray;
DataAdapter dataAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
listView = (ListView)findViewById(R.id.test_listView);
dataAdapter = new DataAdapter(this, R.layout.row_layout);
listView.setAdapter(dataAdapter);
JSON_String = getIntent().getExtras().getString("JSON_Data");
try {
jsonObject = new JSONObject(JSON_String);
jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
String jobid,problem,resolution;
while(count<jsonObject.length()){
JSONObject JO = jsonArray.getJSONObject(count);
jobid = JO.getString("jobid");
problem = JO.getString("problem");
resolution = JO.getString("resolution");
Data data = new Data(jobid,problem,resolution);
dataAdapter.add(data);
count++;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Here is the code for my DataAdapter:
public class DataAdapter extends ArrayAdapter{
List list = new ArrayList();
public DataAdapter(Context context, int resource) {
super(context, resource);
}
public void add(Data object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
row = convertView;
DataHolder dataHolder;
if(row == null){
LayoutInflater layoutInflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row_layout,parent,false);
dataHolder = new DataHolder();
dataHolder.tx_jobid = (TextView) row.findViewById(R.id.tx_jobid);
dataHolder.tx_problem = (TextView) row.findViewById(R.id.tx_problem);
dataHolder.tx_resolution = (TextView) row.findViewById(R.id.tx_resolution);
row.setTag(dataHolder);
}else{
dataHolder = (DataHolder)row.getTag();
}
Data data = (Data)this.getItem(position);
dataHolder.tx_jobid.setText(data.getJobid());
dataHolder.tx_problem.setText(data.getProblem());
dataHolder.tx_resolution.setText(data.getResolution());
return row;
}
static class DataHolder{
TextView tx_jobid,tx_problem,tx_resolution;
}
}
and here is what it displays when clicking on "Parse JSON" button.
listView empty after population
Any help or advise on why its not displaying would be much appreciated!
Thanks in advance!
your problem seems to be here :
while(count<jsonObject.length()){
you're not looping using the number of array elements but using the number of mapped key:value object which is one (the "server_response") , you have to change this line to :
while(count<jsonArray.length()){
,
you have just the first element showing because jsonObject.length() will return 1 since it have just one element.
from the doc, JSONObject, length() method:
Returns the number of name/value mappings in this object.
and in your case you have just one name/value mapped ("server_response":[array items...])
Check in Test.java. I think You are setting the adapter to the listview before adding data to it
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
listView = (ListView)findViewById(R.id.test_listView);
dataAdapter = new DataAdapter(this, R.layout.row_layout);
JSON_String = getIntent().getExtras().getString("JSON_Data");
try {
jsonObject = new JSONObject(JSON_String);
jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
String jobid,problem,resolution;
while(count<jsonObject.length()){
JSONObject JO = jsonArray.getJSONObject(count);
jobid = JO.getString("jobid");
problem = JO.getString("problem");
resolution = JO.getString("resolution");
Data data = new Data(jobid,problem,resolution);
dataAdapter.add(data);
count++;
}
} catch (JSONException e) {
e.printStackTrace();
}
listView.setAdapter(dataAdapter); //change effected
}

2 recycler view adapter , the first showing images the second shows error No adapter attached; skipping layout

I have 2 recycler view adapter, the first is working perfect , the second one I am having the below error,
E/RecyclerView: No adapter attached; skipping layout
is it possible this is the mistake ?
if (mListener != null)
mListener.myMethod(Listitem);
both have different adapter
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView mRecyclerView1;
private RecyclerView.Adapter mAdapter1;
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(
new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
RecyclerOkHttpHandler handler = new RecyclerOkHttpHandler( this, new RecyclerOkHttpHandler.MyInterface() {
#Override
public void myMethod(ArrayList result) {
mAdapter = new MyAdapter(result,Search.this);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter );
}
});
handler.execute();
//second recycler
mRecyclerView1 = (RecyclerView) findViewById(R.id.my_recycler_view1);
mRecyclerView1.setHasFixedSize(true);
mRecyclerView1.setLayoutManager(
new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
RecyclerOkHttpHandler1 handler1 = new RecyclerOkHttpHandler1( this, new RecyclerOkHttpHandler1.MyInterface() {
#Override
public void myMethod(ArrayList result1) {
mAdapter1 = new MyAdapter1(result1,Search.this);
mAdapter1.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter1);
}
});
handler1.execute();
this is RecyclerOkHttpHandler
public class RecyclerOkHttpHandler extends AsyncTask<String, Void, String> {
private Context mContext;
private MyInterface mListener;
public RecyclerOkHttpHandler (Context context, MyInterface mListener){
mContext = context;
this.mListener = mListener;
}
public interface MyInterface {
public void myMethod(ArrayList result);
}
private final String Fetch_URL = "http://je.com/getdata.php";
// ArrayList<Listitem> Listitem;
ArrayList<CategoryList> Listitem;
int resulta;
OkHttpClient httpClient = new OkHttpClient();
ListView list;
String myJSON;
JSONArray peoples = null;
InputStream inputStream = null;
#Override
protected String doInBackground(String... params) {
Log.d("okhttp Fetch_URL", Fetch_URL);
Request.Builder builder = new Request.Builder();
builder.url(Fetch_URL);
Request request = builder.build();
String result = null;
try {
Response response = httpClient.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
inputStream = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
result = sb.toString();
resulta = 1; //"Success
// return response.body().bytes();
} catch (Exception e) {
Toast.makeText(mContext, "Connection failed, check your connection",
Toast.LENGTH_LONG).show();
e.printStackTrace(); }
finally {
try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
}
return result;
}
#Override
protected void onPostExecute(String result){
if( resulta ==1){
myJSON=result;
Log.e("result",result);
showList();
}
else{
Log.e("d","there is an error on postexecute in okhhttphandler.java");
}
}
protected void showList(){
try {
JSONObject jsonObj = new JSONObject(myJSON);
peoples = jsonObj.getJSONArray("result");
System.out.println("Length:"+peoples.length());
int J_length=peoples.length()-1;
//JSONObject maxj = peoples.getJSONObject(peoples.length() - 1);
// max of arrray
jsonObj= peoples.getJSONObject(J_length);
String j_id= jsonObj.getString("id");
int _id = Integer.parseInt(j_id);
// if (_id < d_id) {
System.out.println("Getting json result ");
Listitem = new ArrayList<CategoryList>();
for (int i = 0; i < peoples.length(); i++) {
JSONObject c = peoples.getJSONObject(i);
// String id ="2";
String id = c.getString("id");
String url = c.getString("url");
int intid = 0;
try {
intid = Integer.parseInt(id.toString());
} catch (NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
// DatabaseHandler db = new DatabaseHandler(mContext);
Log.d("Insert: ", "Inserting ..");
//db.addObjects(new Objects(intid, "Image1", url, "IMAGES", "Leb Funny"));
Listitem.add(new CategoryList(id, url));
System.out.println(Listitem);
}
//}
if (mListener != null)
mListener.myMethod(Listitem);
// GridViewAdapter adapter = new GridViewAdapter(mContext, R.layout.grid_item_layout, Listitem);
// gridView.setAdapter(gridAdapter);
// adapter.notifyDataSetChanged();
// list.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
RecyclerOkHttpHandler1 class
public class RecyclerOkHttpHandler1 extends AsyncTask<String, Void, String> {
private Context mContext;
private MyInterface mListener;
public RecyclerOkHttpHandler1(Context context, MyInterface mListener){
mContext = context;
this.mListener = mListener;
}
public interface MyInterface {
public void myMethod(ArrayList result);
}
private final String Fetch_URL = "http://je.com/getdata.php";
// ArrayList<Listitem> Listitem;
ArrayList<CategoryList> Listitem;
int resulta;
OkHttpClient httpClient = new OkHttpClient();
ListView list;
String myJSON;
JSONArray peoples = null;
InputStream inputStream = null;
#Override
protected String doInBackground(String... params) {
Log.d("okhttp Fetch_URL", Fetch_URL);
Request.Builder builder = new Request.Builder();
builder.url(Fetch_URL);
Request request = builder.build();
String result = null;
try {
Response response = httpClient.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
inputStream = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
result = sb.toString();
resulta = 1; //"Success
// return response.body().bytes();
} catch (Exception e) {
Toast.makeText(mContext, "Connection failed, check your connection",
Toast.LENGTH_LONG).show();
e.printStackTrace(); }
finally {
try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
}
return result;
}
#Override
protected void onPostExecute(String result){
if( resulta ==1){
myJSON=result;
Log.e("result",result);
showList();
}
else{
Log.e("d","there is an error on postexecute in okhhttphandler.java");
}
}
protected void showList(){
try {
JSONObject jsonObj = new JSONObject(myJSON);
peoples = jsonObj.getJSONArray("result");
System.out.println("Length:"+peoples.length());
int J_length=peoples.length()-1;
//JSONObject maxj = peoples.getJSONObject(peoples.length() - 1);
// max of arrray
jsonObj= peoples.getJSONObject(J_length);
String j_id= jsonObj.getString("id");
int _id = Integer.parseInt(j_id);
System.out.println(j_id);
//max of
// if (_id < d_id) {
System.out.println("Getting json result ");
Listitem = new ArrayList<CategoryList>();
for (int i = 0; i < peoples.length(); i++) {
JSONObject c = peoples.getJSONObject(i);
// String id ="2";
String id = c.getString("id");
String url = c.getString("url");
int intid = 0;
try {
intid = Integer.parseInt(id.toString());
} catch (NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
// DatabaseHandler db = new DatabaseHandler(mContext);
Log.d("Insert: ", "Inserting ..");
//db.addObjects(new Objects(intid, "Image1", url, "IMAGES", "Leb Funny"));
Listitem.add(new CategoryList(id, url));
System.out.println(Listitem);
}
//}
if (mListener != null)
mListener.myMethod(Listitem);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
my adapter
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<CategoryList> mDataset;
Context mContext;
public class ImageViewHolder extends RecyclerView.ViewHolder {
//ImageView mImage;
public TextView txtHeader;
public TextView txtFooter;
public ImageView image;
public ImageViewHolder(View itemView) {
super (itemView);
txtHeader = (TextView) itemView.findViewById(R.id.firstLine);
txtFooter = (TextView) itemView.findViewById(R.id.secondLine);
image = (ImageView) itemView.findViewById(R.id.imagecateg);
}
}
public void add(int position, CategoryList item) { //changed from string to listitem
mDataset.add(position, item);
notifyItemInserted(position);
}
public void remove(String item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<CategoryList> myDataset, Context context) {
mDataset = myDataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_search, parent, false);
// set the view's size, margins, paddings and layout parameters
ImageViewHolder vh = new ImageViewHolder(v);
return vh;
}
private static final int TYPE_IMAGE = 1;
private static final int TYPE_GROUP = 2;
#Override
public int getItemViewType(int position) {
// here your custom logic to choose the view type
return position;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(RecyclerView.ViewHolder TextViewHolder, int position) {
ImageViewHolder viewHolder = (ImageViewHolder) TextViewHolder;
// viewHolder.txtHeader.setText(...)
final CategoryList item;
// final String name = mDataset.get(position);
item = mDataset.get(position);
// viewHolder.txtHeader.setText(mDataset.get(position));
// this to be removed when added text
// viewHolder.txtHeader.setText(mDataset.get(position).getUrl());
Picasso.with(mContext)
.load(item.getUrl())
.placeholder(R.drawable.logo)
.fit()
.noFade()
.into(viewHolder.image);
/* viewHolder.txtFooter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
remove(item);
}
});*/
// viewHolder.txtFooter.setText("Footer: " + mDataset.get(position));
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
my adapter 1
public class MyAdapter1 extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<CategoryList> mDataset;
Context mContext;
public class ImageViewHolder extends RecyclerView.ViewHolder {
//ImageView mImage;
public TextView txtHeader;
public TextView txtFooter;
public ImageView image;
public ImageViewHolder(View itemView) {
super (itemView);
txtHeader = (TextView) itemView.findViewById(R.id.firstLine);
txtFooter = (TextView) itemView.findViewById(R.id.secondLine);
image = (ImageView) itemView.findViewById(R.id.imagecateg);
}
}
public void add(int position, CategoryList item) { //changed from string to listitem
mDataset.add(position, item);
notifyItemInserted(position);
}
public void remove(String item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter1(ArrayList<CategoryList> myDataset, Context context) {
mDataset = myDataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_search, parent, false);
// set the view's size, margins, paddings and layout parameters
ImageViewHolder vh = new ImageViewHolder(v);
return vh;
}
private static final int TYPE_IMAGE = 1;
private static final int TYPE_GROUP = 2;
#Override
public int getItemViewType(int position) {
// here your custom logic to choose the view type
return position;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(RecyclerView.ViewHolder TextViewHolder, int position) {
ImageViewHolder viewHolder = (ImageViewHolder) TextViewHolder;
// viewHolder.txtHeader.setText(...)
final CategoryList item;
// final String name = mDataset.get(position);
item = mDataset.get(position);
// viewHolder.txtHeader.setText(mDataset.get(position));
// this to be removed when added text
// viewHolder.txtHeader.setText(mDataset.get(position).getUrl());
Picasso.with(mContext)
.load(item.getUrl())
.placeholder(R.drawable.logo)
.fit()
.noFade()
.into(viewHolder.image);
/* viewHolder.txtFooter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
remove(item);
}
});*/
// viewHolder.txtFooter.setText("Footer: " + mDataset.get(position));
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
Here you are setting adapter for mRecyclerView
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(
new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
RecyclerOkHttpHandler handler = new RecyclerOkHttpHandler( this, new RecyclerOkHttpHandler.MyInterface() {
#Override
public void myMethod(ArrayList result) {
mAdapter = new MyAdapter(result,Search.this);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter );
}
});
handler.execute();
And here again you are setting adapter for same mRecyclerView, not for mRecyclerView1
//second recycler
mRecyclerView1 = (RecyclerView) findViewById(R.id.my_recycler_view1);
mRecyclerView1.setHasFixedSize(true);
mRecyclerView1.setLayoutManager(
new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
RecyclerOkHttpHandler1 handler1 = new RecyclerOkHttpHandler1( this, new RecyclerOkHttpHandler1.MyInterface() {
#Override
public void myMethod(ArrayList result1) {
mAdapter1 = new MyAdapter1(result1,Search.this);
mAdapter1.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter1);
}
});
handler1.execute();
This is the reason for the issue (E/RecyclerView: No adapter attached; skipping layout).

Problems with Picasso and Recyclerview - Images get refreshed on scrolling but in the wrong imageviews

I am working on a simple app where I search for a Tv show, where the app generates a GET request to TMDB. From there I am trying to display the images and details of results in a cardview. I am using Picasso for loading the images from TMDB and it works fine. The problem is when I scroll, the images loaded first get refreshed to the other imageviews instead of those show specific images.
This is my asynctask code
class JsonTask extends AsyncTask<String,String,String[][]>{
private List<FeedItem> persons;
String [][] Finalarray = new String[200][3];
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
protected String[][] doInBackground(String... params) {
HttpURLConnection urlConnection = null;
StringBuffer buffer = new StringBuffer();
String line;
BufferedReader reader = null;
try{
URL Request1 = new URL(params[0]);
urlConnection = (HttpURLConnection) Request1.openConnection();
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.connect();
int responseCode = urlConnection.getResponseCode();
Log.d("DEBUG_TAG", "The response code is: " + responseCode + " " + urlConnection.getResponseMessage());
InputStream in = urlConnection.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
while ((line = reader.readLine())!=null){
Log.i("check","Line is"+line);
buffer.append(line);
}
String jsonobjectt= buffer.toString();
JSONObject parentJson = new JSONObject(jsonobjectt);
JSONArray parentArray = (JSONArray) parentJson.get("results");
dataobtained=parentJson.getInt("total_results");
for(int i = 0; i<parentJson.getInt("total_results"); i++){
JSONObject temp = parentArray.getJSONObject(i);
Finalarray[i][0] = temp.getString("original_name");
Finalarray[i][1] = temp.getString("first_air_date");
Finalarray[i][2] = temp.getString("poster_path");
}
}
catch (MalformedURLException e){
Log.i("I do", "eee1");
e.printStackTrace();
} catch (IOException e) {
Log.i("I do", "eee2");
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
Log.i("I do", "eee3");
if(urlConnection!=null)
urlConnection.disconnect();
try {
if(reader!=null)
reader.close();
} catch (IOException e) {
Log.i("I do", "eee4");
e.printStackTrace();
}
}
return Finalarray;
}
#Override
protected void onPostExecute(String[][] result) {
persons = new ArrayList<>();
for(int i=0;i<dataobtained;i++){
//if(!result[i][0].isEmpty()&&result[i][2]!=null)
persons.add(new FeedItem(result[i][0], result[i][1],"http://image.tmdb.org/t/p/w500"+result[i][2],searchpagee.this));
}
new Thread(new Runnable() {
#Override
public void run() {
}
}).start();
mRecyclerView.setLayoutManager(llm);
RVAdapter adapter = new RVAdapter(persons);
mRecyclerView.setAdapter(adapter);
}
}
}
And this is my Recycleradapter code
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{
List<FeedItem> persons;
RVAdapter(List<FeedItem> persons){
this.persons = persons;
}
public static class PersonViewHolder extends RecyclerView.ViewHolder {
public static ImageView personPhoto;
CardView cv;
TextView personName;
TextView personAge;
PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
personName = (TextView)itemView.findViewById(R.id.titleCir);
personAge = (TextView)itemView.findViewById(R.id.contentsCir);
personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
}
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardv, viewGroup, false);
PersonViewHolder pvh = new PersonViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
personViewHolder.personName.setText(persons.get(i).title);
personViewHolder.personAge.setText(persons.get(i).content);
Picasso.with(persons.get(i).context).load(persons.get(i).photoId).placeholder(R.drawable.placeholder).fit().into(PersonViewHolder.personPhoto);
}
#Override
public int getItemCount() {
return persons == null ? 0 : persons.size();
}
}
This is before scrolling
While scrolling. Images get repeated
Add a bindView() in your PersonViewHolder like this,
public static class PersonViewHolder extends RecyclerView.ViewHolder {
public static ImageView personPhoto;
CardView cv;
TextView personName;
TextView personAge;
PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
personName = (TextView)itemView.findViewById(R.id.titleCir);
personAge = (TextView)itemView.findViewById(R.id.contentsCir);
personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
}
public void bindView(int i) {
personName.setText(persons.get(i).title);
personAge.setText(persons.get(i).content);
Picasso.with(persons.get(i).context).load(persons.get(i).photoId).placeholder(R.drawable.placeholder).fit().into(personPhoto);
}
}
And in bindViewHolder you need to call bindView() to bind each element of the list with appropriate elements.
#Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
try {
personViewHolder.bindView(i);
} catch(Exception e) {e.printStackTrace();}
}

Categories

Resources