RecyclerView Does Not Load Data Initially - java

I'm using a Spinner and a RecyclerView in a Fragment in my Android project.
My RecyclerView does not show any data until I select an item in the Spinner.
What should I do to show the RecyclerView's result without selecting an item from the Spinner?
at the first recycler should show 10 attraction.
My code:
Attraction.java
package com.rayantec.reservation.reservationdemo.Model;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.rayantec.reservation.reservationdemo.Adapter.AttractionAdapter;
import com.rayantec.reservation.reservationdemo.G;
import com.rayantec.reservation.reservationdemo.Lists.AttractionList;
import com.rayantec.reservation.reservationdemo.Lists.CityList;
import com.rayantec.reservation.reservationdemo.R;
import com.toptoche.searchablespinnerlibrary.SearchableSpinner;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class Attractions extends Fragment {
RecyclerView recyclerView;
ArrayList<AttractionList> AttractionData = new ArrayList<>();
public SearchableSpinner spinnerCitiest;
ArrayList<CityList> cityLists = new ArrayList<>();
ProgressDialog progressDialog;
public void showCity(View view) {
spinnerCitiest = (SearchableSpinner) view.findViewById(R.id.SpinnerCitiestId);
spinnerCitiest.setTitle("Please Select City");
spinnerCitiest.setPositiveButton("Ok");
//spinnerCitiest.setSelection(2);
JsonArrayRequest JsonObjectRequest = new JsonArrayRequest(Request.Method.GET, G.serverURL + "/android/jsyncs/getdata/city", null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
//progressDialog.dismiss();
try {
for (int i = 0; i < response.length(); i++) {
JSONObject jsonOBJ = response.getJSONObject(i);
String id = jsonOBJ.getString("id");
String title = jsonOBJ.getString("title");
cityLists.add(new CityList(id, title));
}
} catch (JSONException e1) {
e1.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//progressDialog.dismiss();
Toast.makeText(G.context, "Server Connection error", Toast.LENGTH_SHORT).show();
}
});
JsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(7000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestQueue = Volley.newRequestQueue(G.context);
requestQueue.add(JsonObjectRequest);
ArrayAdapter<CityList> adapterCities = new ArrayAdapter<CityList>(G.context, android.R.layout.simple_spinner_item, cityLists);
adapterCities.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerCitiest.setAdapter(adapterCities);
spinnerCitiest.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
CityList cityList = (CityList) adapterView.getSelectedItem();
Toast.makeText(G.context, "City ID: " + cityList.getId() + ", City Name : " + cityList.getTitle(), Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void showRandomAttractions(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.RecyclerAttracionId);
JsonArrayRequest JsonObjectRequests = new JsonArrayRequest(Request.Method.GET, G.serverURL + "/android/jsyncs/getdata/randattraction", null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
progressDialog.dismiss();
//AttractionList sampledata = new AttractionList();
try {
for (int i = 0; i < response.length(); i++) {
JSONObject jsonOBJs = response.getJSONObject(i);
String id = jsonOBJs.getString("id");
String title = jsonOBJs.getString("title");
String imageUrl = jsonOBJs.getString("imageUrl");
String location = jsonOBJs.getString("location");
String type = jsonOBJs.getString("type");
String body = jsonOBJs.getString("body");
AttractionData.add(new AttractionList(id, title, body, location, imageUrl, type));
}
} catch (JSONException e1) {
e1.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(G.context, "Server Connection error", Toast.LENGTH_SHORT).show();
}
});
JsonObjectRequests.setRetryPolicy(new DefaultRetryPolicy(7000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestQueue = Volley.newRequestQueue(G.context);
requestQueue.add(JsonObjectRequests);
recyclerView.setLayoutManager(new LinearLayoutManager(G.context, LinearLayoutManager.VERTICAL, false));
AttractionAdapter attractionAdapter = new AttractionAdapter(AttractionData);
recyclerView.setAdapter(attractionAdapter);
}
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.attraction, container, false);
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Please wait ...");
progressDialog.setCancelable(false);
progressDialog.show();
showCity(view);
showRandomAttractions(view);
return view;
}
}
Attraction.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="#+id/cardviewattraction"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:padding="3dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.toptoche.searchablespinnerlibrary.SearchableSpinner
android:id="#+id/SpinnerCitiestId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:padding="3dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerAttracionId"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/cardviewattraction"
tools:ignore="MissingConstraints" />
</android.support.constraint.ConstraintLayout>
AttractionAdapter
package com.rayantec.reservation.reservationdemo.Adapter;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.rayantec.reservation.reservationdemo.Lists.AttractionList;
import com.rayantec.reservation.reservationdemo.R;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class AttractionAdapter extends RecyclerView.Adapter<AttractionAdapter.AttractionViewHolder> {
ArrayList<AttractionList> attractionArrayList;
public AttractionAdapter(ArrayList<AttractionList> attractions) {
attractionArrayList = new ArrayList<>();
attractionArrayList = attractions;
}
#NonNull
#Override
public AttractionViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_attraction, parent, false);
return new AttractionViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull AttractionViewHolder holder, int position) {
AttractionList dataModel = attractionArrayList.get(position);
holder.txtTitle.setText(dataModel.getTitle());
holder.txtBody.setText(dataModel.getBody());
holder.txtType.setText(dataModel.getType());
holder.txtLocation.setText(dataModel.getLocation());
Picasso.get().load(dataModel.getImgUrl()).resize(130, 100).centerCrop().into(holder.imgAttraction);
}
#Override
public int getItemCount() {
return attractionArrayList.size();
}
public class AttractionViewHolder extends RecyclerView.ViewHolder{
public ImageView imgAttraction;
public TextView txtTitle;
public TextView txtBody;
public TextView txtLocation;
public TextView txtType;
public AttractionViewHolder(View itemView) {
super(itemView);
imgAttraction = (ImageView)itemView.findViewById(R.id.img_recycler_attraction);
txtTitle = (TextView)itemView.findViewById(R.id.txt_recycler_attractionTitle);
txtBody = (TextView)itemView.findViewById(R.id.txt_recycler_attractionBody);
txtLocation = (TextView)itemView.findViewById(R.id.txt_recycler_attractionPositions);
txtType = (TextView)itemView.findViewById(R.id.txt_recycler_attractionType);
}
//
}
}
AttractionList.java
package com.rayantec.reservation.reservationdemo.Lists;
public class AttractionList {
private String id;
private String title;
private String body;
private String location;
private String imgUrl;
public AttractionList(String id, String title, String body, String location, String imgUrl, String type) {
this.id = id;
this.title = title;
this.body = body;
this.location = location;
this.imgUrl = imgUrl;
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
}

There are a few things that you should test, did you check to see if you're receiving the onResponse callback in your showRandomAttractions(View view) method? This would verify that the Get call is working as intended.
If you are receiving that onResponse call, try calling attractionAdapter.notifyDataSetChanged() after your for-loop when you're done adding data to your AttractionData ArrayList. It would look like this:
try {
for (int i = 0; i < response.length(); i++) {
JSONObject jsonOBJs = response.getJSONObject(i);
String id = jsonOBJs.getString("id");
String title = jsonOBJs.getString("title");
String imageUrl = jsonOBJs.getString("imageUrl");
String location = jsonOBJs.getString("location");
String type = jsonOBJs.getString("type");
String body = jsonOBJs.getString("body");
AttractionData.add(new AttractionList(id, title, body, location, imageUrl, type));
// Notify your adapter that its data has changed.
attractionAdapter.notifyDataSetChanged();
}
} catch (JSONException e1) {
e1.printStackTrace();
}
You can check out this documentation for more info on how notifyDataSetChanged works.

I believe your request to the server to collect the Data is Asynchronous and happens on a Worker Thread. If that's the case then your View is rendered before actually getting the data.
I would suggest to add a setData function in your adapter:
public void setData(ArrayList<Attractions> attractions){
this.attractionArrayList = attractions
notifyDataSetChanged()
}
Then on your activity when you get the response and build the array of attraction, just call adapter.setData(attractions)
UPDATE:
Make sure to set your adapter when the view is actually initialized, so you need to call it on onViewCreated:
public void onViewCreated(View view,Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
showCity(view);
showRandomAttractions(view);
}

by replace this line after try/catch this problem solved
recyclerView.setLayoutManager(new LinearLayoutManager(G.context, LinearLayoutManager.VERTICAL, false));
AttractionAdapter attractionAdapter = new AttractionAdapter(AttractionData);
recyclerView.setAdapter(attractionAdapter);

Related

My news page in my app isn't retrieving any news and only a blank white page is being displayed instead of a newsfeed

I am currently working on Android Studio 4.0, Build #AI-193.6911.18.40.6514223.
Upon entering the news page, I am being shown a blank page. It appears that the API is not retrieving the news it's supposed to. I've double checked my entire app for any typos (in case it doesn't match the API parameters). Everything appears right but the API is not retrieving the data.
I have attached below the code with respect to the problem.
newspage.java:
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import com.example.nvirone.API.ApiClient;
import com.example.nvirone.API.ApiInterface;
import com.example.nvirone.Models.Article;
import com.example.nvirone.Models.News;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class Newspage extends AppCompatActivity {
public static final String API_KEY = "(unique API key)";
private RecyclerView recyclerView;
private Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private List<Article> articles = new ArrayList<>();
private String TAG = Newspage.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_newspage);
recyclerView = findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new Adapter(articles, Newspage.this);
recyclerView.setAdapter(adapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setNestedScrollingEnabled(false);
LoadJson();
}
public void LoadJson(){
ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
String country = Utils.getCountry();
Call<News> call;
call = apiInterface.getNews(country, API_KEY);
call.enqueue(new Callback<News>() {
#Override
public void onResponse(Call<News> call, Response<News> response) {
if (response.isSuccessful() && response.body().getArticle()!=null){
articles.clear();
articles = response.body().getArticle();
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<News> call, Throwable t) {
Toast.makeText(Newspage.this,"NO result",Toast.LENGTH_LONG).show();
}
});
}
}
Newsindetail.java:
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class NewInDetail extends AppCompatActivity {
WebView webView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_in_detail);
Intent intent = getIntent();
String url = intent.getStringExtra("url");
webView = findViewById(R.id.webView);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl(url);
}
}
Adapter:
package com.example.nvirone;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.example.nvirone.Models.Article;
import com.squareup.picasso.Picasso;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
private List<Article> articles;
private Context context;
private AdapterView.OnItemClickListener OnItemClickListener;
private OnItemClickListener onItemCLickListener;
public Adapter(List<Article> articles, Context context) {
this.articles = articles;
this.context = context;
}
public Adapter() {
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holders, int position) {
final MyViewHolder holder = holders;
final Article model = articles.get(position);
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(Utils.getRandomDrawbleColor());
requestOptions.error(Utils.getRandomDrawbleColor());
requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
requestOptions.centerCrop();
Glide.with(context).load(model.getUrlToImage()).apply(requestOptions)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
holder.progressBar.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
holder.progressBar.setVisibility(View.GONE);
return false;
}
})
.transition(DrawableTransitionOptions.withCrossFade())
.into(holder.imageView);
holder.title.setText(model.getTitle());
holder.desc.setText(model.getDescription());
holder.source.setText(model.getSource().getName());
holder.time.setText('\u2022' + Utils.DateToTimeFormat(model.getPublishedAt()));
holder.published.setText(Utils.DateToTimeFormat(model.getPublishedAt()));
holder.author.setText(model.getAuthor());
String imageURL = model.getUrlToImage();
Picasso.get().load(imageURL).into(holder.imageView);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,NewInDetail.class);
intent.putExtra("url",model.getUrl());
context.startActivity(intent);
}
});
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
return new MyViewHolder(view, onItemCLickListener);
}
#Override
public int getItemCount() {
return articles.size();
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemCLickListener = onItemClickListener;
}
public interface OnItemClickListener{
void onItemClick(View view, int position);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView title, desc, author, published, source, time;
ImageView imageView;
ProgressBar progressBar;
OnItemClickListener onItemClickListener;
CardView cardView;
public MyViewHolder(#NonNull View itemView, OnItemClickListener onItemClickListener) {
super(itemView);
itemView.setOnClickListener(this);
title = itemView.findViewById(R.id.title);
desc = itemView.findViewById(R.id.desc);
author = itemView.findViewById(R.id.author);
published = itemView.findViewById(R.id.publishedAt);
source = itemView.findViewById(R.id.source);
time = itemView.findViewById(R.id.time);
imageView = itemView.findViewById(R.id.img);
progressBar = itemView.findViewById(R.id.progress_load_photo);
cardView = itemView.findViewById(R.id.cardView);
this.onItemClickListener = onItemCLickListener;
}
#Override
public void onClick(View view) {
onItemClickListener.onItemClick(view, getAdapterPosition());
}
}
}
ApiClient:
package com.example.nvirone.API;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
public static final String BaseURL = "https://newsapi.org/v2/";
public static Retrofit retrofit ;
public static Retrofit getApiClient(){
if(retrofit==null){
retrofit = new Retrofit.Builder().baseUrl(BaseURL).client(getUnsafeOkHttpClient().build()).addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
public static OkHttpClient.Builder getUnsafeOkHttpClient(){
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
return builder;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
ApiInterface:
package com.example.nvirone.API;
import com.example.nvirone.Models.News;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface ApiInterface {
#GET("top-headlines")
Call<News> getNews(
#Query("country") String country,
#Query("apiKey") String apiKey
);
}
Utils:
package com.example.nvirone;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
public class Utils {
public static ColorDrawable[] vibrantLightColorList =
{
new ColorDrawable(Color.parseColor("#ffeead")),
new ColorDrawable(Color.parseColor("#93cfb3")),
new ColorDrawable(Color.parseColor("#fd7a7a")),
new ColorDrawable(Color.parseColor("#faca5f")),
new ColorDrawable(Color.parseColor("#1ba798")),
new ColorDrawable(Color.parseColor("#6aa9ae")),
new ColorDrawable(Color.parseColor("#ffbf27")),
new ColorDrawable(Color.parseColor("#d93947"))
};
public static ColorDrawable getRandomDrawbleColor() {
int idx = new Random().nextInt(vibrantLightColorList.length);
return vibrantLightColorList[idx];
}
public static String DateToTimeFormat(String oldstringDate){
PrettyTime p = new PrettyTime(new Locale(getCountry()));
String isTime = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
Locale.ENGLISH);
Date date = sdf.parse(oldstringDate);
isTime = p.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return isTime;
}
public static String DateFormat(String oldstringDate){
String newDate;
SimpleDateFormat dateFormat = new SimpleDateFormat("E, d MMM yyyy", new Locale(getCountry()));
try {
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.CHINA).parse(oldstringDate);
assert date != null;
newDate = dateFormat.format(date);
} catch (ParseException e) {
e.printStackTrace();
newDate = oldstringDate;
}
return newDate;
}
public static String getCountry(){
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
}
Parameters according to the API:
NEWS:
package com.example.nvirone.Models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class News {
#SerializedName("status")
#Expose
private String status;
#SerializedName("totalResults")
#Expose
private int totalResult;
#SerializedName("articles")
#Expose
private List<Article> article;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getTotalResult() {
return totalResult;
}
public void setTotalResult(int totalResult) {
this.totalResult = totalResult;
}
public List<Article> getArticle() {
return article;
}
public void setArticle(List<Article> article) {
this.article = article;
}
}
Article :
package com.example.nvirone.Models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Article {
#SerializedName("source")
#Expose
private Source source;
#SerializedName("author")
#Expose
private String author;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("url")
#Expose
private String url;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
#SerializedName("publishedAt")
#Expose
private String publishedAt;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
Source:
package com.example.nvirone.Models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Source {
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The cardview that is supposed to display the newsfeed :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="11dp"
android:layout_marginRight="11dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
app:cardElevation="#dimen/cardview_default_elevation"
app:cardCornerRadius="15dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/img"
android:scaleType="centerCrop"
android:transitionName="img"
tools:ignore= "UnusedAttribute"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="#+id/shadow_bottom"
android:src="#drawable/bottom_shadow"
android:layout_alignBottom="#+id/img" />
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#android:style/Widget.ProgressBar.Small"
android:id="#+id/progress_load_photo"
android:layout_marginTop="70dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="#+id/author"
android:drawablePadding="10dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#android:color/white"
android:singleLine="true"
android:text="Author"
android:gravity="bottom"
android:layout_marginRight="160dp"
android:layout_alignLeft="#+id/title"
android:layout_alignStart="#+id/title"
android:layout_alignRight="#+id/layoutDate"
android:layout_alignTop="#+id/layoutDate"
android:layout_alignEnd="#+id/layoutDate"/>
<FrameLayout
android:id="#+id/layoutDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/img"
android:background="#drawable/round_white"
android:padding="5dp"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_marginTop="50dp">
<ImageView
android:src="#drawable/ic_date"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#606060"
android:id="#+id/publishedAt"
android:layout_marginLeft="27dp"
android:layout_marginRight="10dp"
android:text="01 January 2000"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:textStyle="bold"
android:textColor="#color/colorTextTitle"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:text="Title"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:layout_below="#id/img"
android:id="#+id/title"/>
<TextView
android:id="#+id/desc"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginRight="16dp"
android:layout_below="#+id/title"
android:layout_marginLeft="16dp"
android:layout_marginTop="5dp"
android:text="Desc"/>
<TextView
android:id="#+id/source"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_below="#+id/desc"
android:layout_marginLeft="16dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:fontFamily="sans-serif-light"
android:textStyle="bold"
android:textColor="#color/colorTextTitle"
android:ellipsize="end"
android:singleLine="true"
android:drawablePadding="10dp"
android:maxLines="1"
android:text="Source"/>
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_below="#+id/desc"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_toRightOf="#+id/source"
android:ellipsize="end"
android:singleLine="true"
android:drawablePadding="10dp"
android:maxLines="1"
android:text="Time"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
EDIT :
I have added some code in the API interface as follows and the same problem has come up again after trying to use this query :
#GET("everything")
Call<News> getNewsSearch(
#Query("q") String Keyword,
#Query("language") String language,
#Query("SortBy") String sortBy,
#Query("apiKey") String apiKey
);
You need to add this method in your Adapter.java:
public void addArticles(List<Article> articles) {
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
And use it this way in your NewsPage.java:
public void LoadJson() {
ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
String country = Utils.getCountry();
Call<News> call;
call = apiInterface.getNews(country, API_KEY);
call.enqueue(new Callback<News>() {
#Override
public void onResponse(Call<News> call, Response<News> response) {
List<Article> newArticles = response.body().getArticle();
if (response.isSuccessful() && newArticles != null) {
adapter.addArticles(newArticles);
}
}
#Override
public void onFailure(Call<News> call, Throwable t) {
Toast.makeText(NewsPage.this, "NO result", Toast.LENGTH_LONG).show();
}
});
}

ItemClickListener not working in Fragment RecyclerView with onclick

I've been following this tutorial: Tutorial
To make a json recyclerviewer with onclick, but i wanted to use Fragments instead of activities.
I've figured everything out until the point of the onClick.
My problem is the setOnItemClickListener is not taking my getActivity()
I've tried so much, but i just cant see the bright light.
If anyone could help me out that would be totally awesome!
Me only real problem is that the getActivity is giving a red line in the:
fNieuwsAdapter.setOnItemClickListener(getActivity());
NieuwsFragment.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import java.util.ArrayList;
public class NieuwsFragment extends Fragment implements NieuwsAdapter.OnItemClickListener {
public static final String EXTRA_URL = "nieuwsImageUrl";
public static final String EXTRA_HEADING = "nieuwsHeading";
public static final String EXTRA_CONTENT = "nieuwsContent";
private RecyclerView fNieuwsRecyclerView;
private NieuwsAdapter fNieuwsAdapter;
private ArrayList<NieuwsItem> fNieuwsList;
private RequestQueue fNieuwsQueue;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_nieuws, container, false);
fNieuwsRecyclerView = view.findViewById(R.id.recycler_view);
fNieuwsRecyclerView.setHasFixedSize(true);
fNieuwsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
fNieuwsList = new ArrayList<>();
fNieuwsQueue = Volley.newRequestQueue(getActivity());
parseJSON();
return view;
}
private void parseJSON() {
String url = "urlissecretsorry<3butthejsonparsingworks";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
public String nieuwsImageUrl;
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("posts");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
JSONArray attachArray = hit.getJSONArray("attachments");
for (int a = 0; a < attachArray.length(); a++) {
JSONObject attach = attachArray.getJSONObject(a);
nieuwsImageUrl = attach.getString("url");
}
String nieuwsHeading = hit.getString("title");
String nieuwsExcerpt = hit.getString("excerpt");
String nieuwsContent = hit.getString("content");
nieuwsExcerpt = html2text(nieuwsExcerpt);
fNieuwsList.add(new NieuwsItem(nieuwsImageUrl, nieuwsHeading, nieuwsExcerpt,nieuwsContent));
}
fNieuwsAdapter = new NieuwsAdapter(getActivity(), fNieuwsList);
fNieuwsAdapter.setOnItemClickListener(getActivity());
fNieuwsRecyclerView.setAdapter(fNieuwsAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
fNieuwsQueue.add(request);
}
#Override
public void onItemClick(int position) {
Intent detailIntent = new Intent(getActivity(), DetailActivity.class);
NieuwsItem clickedItem = fNieuwsList.get(position);
detailIntent.putExtra(EXTRA_URL, clickedItem.getImageUrl());
detailIntent.putExtra(EXTRA_HEADING, clickedItem.getHeading());
detailIntent.putExtra(EXTRA_CONTENT, clickedItem.getContent());
startActivity(detailIntent);
}
public String html2text(String html) {
try {
return Jsoup.parse(html).text();
} catch (Exception ignored) {
return "";
}
}
}
NieuwsItem.java
public class NieuwsItem {
private String nieuwsImageUrl;
private String nieuwsHeading;
private String nieuwsExcerpt;
private String nieuwsContent;
public NieuwsItem(String imageUrl, String heading, String excerpt, String content){
nieuwsImageUrl = imageUrl;
nieuwsHeading = heading;
nieuwsExcerpt = excerpt;
nieuwsContent = content;
}
public String getImageUrl(){
return nieuwsImageUrl;
}
public String getHeading(){
return nieuwsHeading;
}
public String getExcerpt(){
return nieuwsExcerpt;
}
public String getContent(){
return nieuwsContent;
}
}
NieuwsAdapter.java
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class NieuwsAdapter extends RecyclerView.Adapter<NieuwsAdapter.NieuwsViewHolder> {
private Context NieuwsContext;
private ArrayList<NieuwsItem> NieuwsList;
private OnItemClickListener NieuwsListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
NieuwsListener = listener;
}
public NieuwsAdapter(Context context, ArrayList<NieuwsItem> nieuwslist) {
NieuwsContext = context;
NieuwsList = nieuwslist;
}
#NonNull
#Override
public NieuwsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(NieuwsContext).inflate(R.layout.nieuws_item, parent, false);
return new NieuwsViewHolder(v);
}
#Override
public void onBindViewHolder(NieuwsViewHolder holder, int position) {
NieuwsItem currentitem = NieuwsList.get(position);
String ImageUrl = currentitem.getImageUrl();
String Heading = currentitem.getHeading();
String Excerpt = currentitem.getExcerpt();
holder.NieuwsTextViewHeading.setText(Heading);
holder.NieuwsTextViewExcerpt.setText(Excerpt);
Picasso.get().load(ImageUrl).fit().centerInside().into(holder.NieuwsImageView);
}
#Override
public int getItemCount() {
return NieuwsList.size();
}
public class NieuwsViewHolder extends RecyclerView.ViewHolder {
public ImageView NieuwsImageView;
public TextView NieuwsTextViewHeading;
public TextView NieuwsTextViewExcerpt;
public NieuwsViewHolder(#NonNull View itemView) {
super(itemView);
NieuwsImageView = itemView.findViewById(R.id.nieuws_image);
NieuwsTextViewHeading = itemView.findViewById(R.id.nieuws_heading);
NieuwsTextViewExcerpt = itemView.findViewById(R.id.nieuws_excerpt);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (NieuwsListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
NieuwsListener.onItemClick(position);
}
}
}
});
}
}
}
DetailActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
public class DetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent intent = getIntent();
String imageUrl = intent.getStringExtra("EXTRA_URL");
String creatorName = intent.getStringExtra("EXTRA_HEADING");
String likeCount = intent.getStringExtra("EXTRA_CONTENT");
ImageView imageView = findViewById(R.id.nieuws_detail_image);
TextView textViewHeading = findViewById(R.id.nieuws_detail_heading);
TextView textViewContent = findViewById(R.id.nieuws_detail_content);
Picasso.get().load(imageUrl).fit().centerInside().into(imageView);
textViewHeading.setText(creatorName);
textViewContent.setText("Likes: " + likeCount);
}
}
You cant use NieuwsAdapter.setOnItemClickListener(getActivity()); , unless your activity implements OnItemClickListener interface, but im seeing that your fragment implements OnItemClickListener, so you can use the fragment instead like this :
fNieuwsAdapter.setOnItemClickListener(NieuwsFragment.this);
And by the way, you are sending the data via intent with :
detailIntent.putExtra(EXTRA_URL, clickedItem.getImageUrl());
detailIntent.putExtra(EXTRA_HEADING, clickedItem.getHeading());
detailIntent.putExtra(EXTRA_CONTENT, clickedItem.getContent());
You have to get them with the same parameters (remove the ""):
String imageUrl = intent.getStringExtra(EXTRA_URL);
String creatorName = intent.getStringExtra(EXTRA_HEADING);
String likeCount = intent.getStringExtra(EXTRA_CONTENT);
Hope this helps
change
public NieuwsAdapter(Context context, ArrayList<NieuwsItem> nieuwslist) {
NieuwsContext = context;
NieuwsList = nieuwslist;
}
to
public NieuwsAdapter(Context context, ArrayList<NieuwsItem> nieuwslist, OnItemClickListener mOnClickListener) {
this.NieuwsContext = context;
this.NieuwsList = nieuwslist;
this.NieuwsListener = mOnClickListener;
}
and this
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (NieuwsListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
NieuwsListener.onItemClick(position);
}
}
}
});
change to
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NieuwsListener.onItemClick(int position);
}
});
and then in fragment You can do it like this
fNieuwsAdapter = new NieuwsAdapter(getActivity(), fNieuwsList,new NieuwsAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position)
{
//DoSomethingHere
}
});

CustomAdapter cannot be appllied to Fragment in Android JSON News app

I am creating an News app, am a newbie, Have some errors in MainActivity.Java i couldn't resolve them. Need help!
This is My MainActivity.Java
package com.example.arumugam.newsreader;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.lang.String;
import java.util.List;
public class MainActivity extends Fragment {
public MainActivity() {
// Required empty public constructor
}
private List<newsItem> newsFeed = new ArrayList<>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.activity_main, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("News");
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
JsonObjectRequest newsReq = new JsonObjectRequest(Request.Method.GET,
"https://raw.githubusercontent.com/sumbganesh/temp/master/convertjson.json",
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray newsItem = response.getJSONArray("newsItems");
for (int i = 0; i < newsItem.length(); i++) {
JSONObject temp = newsItem.getJSONObject(i);
String title = temp.getString("title");
String description = temp.getString("description");
String url = temp.getString("url");
String urlToImage = temp.getString("urlToImage");
newsFeed.add(new newsItem(title, description, url, urlToImage));
}
} catch (JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(newsReq);
ArrayAdapter<newsItem> adapter = new customAdapter(newsFeed,getActivity());
ListView newsItems =(ListView) (getActivity().findViewById(R.id.newsItems));
newsItems.setAdapter(adapter);
}
private class customAdapter extends ArrayAdapter<newsItem>{
Activity context;
customAdapter(List<newsItem> newsFeed, Activity context) {
super(getActivity(), R.layout.item, newsFeed);
this.context = context;
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
if (convertView == null){
convertView = getActivity().getLayoutInflater().inflate(R.layout.item, parent, false);
}
newsItem currentItem = newsFeed.get(position);
ImageView newsImage = (ImageView) convertView.findViewById(R.id.leftIco);
TextView newsHeading = (TextView) convertView.findViewById(R.id.heading);
TextView newsDesc = (TextView) convertView.findViewById(R.id.desc);
newsImage.setImageResource(R.mipmap.ic_launcher);
newsHeading.setText(currentItem.getNewsHeading());
newsDesc.setText(String.valueOf((currentItem.getNewsDesc())));
return convertView;
}
}
}
This is my newsItem.java
public class newsItem {
private String newsHeading;
private String newsDesc;
private String newsDescSmall;
private String time;
private String date;
private String url;
private String imageURL;
public newsItem(String newsHeading, String newsDesc, String date, String time) {
this.newsHeading = newsHeading;
this.newsDesc = newsDesc;
this.time = time;
this.date = date;
this.url = url;
this.imageURL = imageURL;
this.newsDescSmall = this.newsDesc.substring(0, 50) + "...";
}
public String getNewsHeading() {
return newsHeading;
}
public String getNewsDesc() {
return newsDesc;
}
public String getNewsDescSmall() {
return newsDescSmall;
}
public String getTime() {
return time;
}
public String getDate() {
return date;
}
public String getUrl() {
return url;
}
public String getImageURL() {
return imageURL;
}
}
This is my item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/leftIco"
android:src="#mipmap/ic_launcher"
android:maxHeight="70dp"
android:maxWidth="70dp"
android:adjustViewBounds="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Description"
android:lineSpacingExtra="-3dp"
android:id="#+id/desc"
android:layout_alignBottom="#+id/leftIco"
android:layout_alignLeft="#+id/heading"
android:layout_alignStart="#+id/heading" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Heading Text"
android:textStyle="bold"
android:id="#+id/heading"
android:scrollHorizontally="true"
android:maxLines="1"
android:layout_marginBottom="15dp"
android:ellipsize="end"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/leftIco"
android:layout_toEndOf="#+id/leftIco"
android:layout_marginLeft="24dp"
android:layout_marginStart="24dp" />
</RelativeLayout>
The problem i am facing is with this line
ArrayAdapter<newsItem> adapter = new customAdapter(newsFeed,getActivity());
Thank you in advance..
Error on Android Studio
Logcat Error
05-10 19:39:01.191 1232-1318/system_process E/Parcel: Class not found when unmarshalling: com.truecaller.service.MissedCallReminder
java.lang.ClassNotFoundException: com.truecaller.service.MissedCallReminder
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:400)
at android.os.Parcel.readParcelableCreator(Parcel.java:2508)
at android.os.Parcel.readParcelable(Parcel.java:2462)
at android.os.Parcel.readValue(Parcel.java:2365)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2732)
at android.os.BaseBundle.unparcel(BaseBundle.java:268)
at android.os.Bundle.putAll(Bundle.java:226)
at android.content.Intent.fillIn(Intent.java:8273)
at
com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:244)
at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:205)
at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:7305)
at android.app.PendingIntent.send(PendingIntent.java:836)
at com.android.server.AlarmManagerService$DeliveryTracker.deliverLocked(AlarmManagerService.java:3187)
at com.android.server.AlarmManagerService.deliverAlarmsLocked(AlarmManagerService.java:2620)
at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:2741)
Caused by: java.lang.ClassNotFoundException: com.truecaller.service.MissedCallReminder
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:1346)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:1406)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at java.lang.Class.classForName(Native Method) 
at java.lang.Class.forName(Class.java:400) 
at android.os.Parcel.readParcelableCreator(Parcel.java:2508) 
at android.os.Parcel.readParcelable(Parcel.java:2462) 
at android.os.Parcel.readValue(Parcel.java:2365) 
at android.os.Parcel.readArrayMapInternal(Parcel.java:2732) 
at android.os.BaseBundle.unparcel(BaseBundle.java:268) 
at android.os.Bundle.putAll(Bundle.java:226) 
at android.content.Intent.fillIn(Intent.java:8273) 
at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:244) 
at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:205) 
at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:7305) 
at android.app.PendingIntent.send(PendingIntent.java:836) 
at com.android.server.AlarmManagerService$DeliveryTracker.deliverLocked(AlarmManagerService.java:3187) 
at com.android.server.AlarmManagerService.deliverAlarmsLocked(AlarmManagerService.java:2620) 
at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.javat:2741) 
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
You should change in customAdapter class
customAdapter(List<newsItem> newsFeed, Context context) {
super(getActivity(), R.layout.item, newsFeed);
this.context = context;
}
and it will work definitely....
i hope this answer help you..
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.lang.String;
import java.util.List;
public class MainActivity extends Fragment {
private List<newsItem> newsFeed = new ArrayList<>();
public MainActivity() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.activity_main, container, false);
getActivity().setTitle("News");
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
JsonObjectRequest newsReq = new JsonObjectRequest(Request.Method.GET,
"https://raw.githubusercontent.com/sumbganesh/temp/master/convertjson.json",
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray newsItem = response.getJSONArray("newsItems");
for (int i = 0; i < newsItem.length(); i++) {
JSONObject temp = newsItem.getJSONObject(i);
String title = temp.getString("title");
String description = temp.getString("description");
String url = temp.getString("url");
String urlToImage = temp.getString("urlToImage");
newsFeed.add(new newsItem(title, description, url, urlToImage));
ArrayAdapter<newsItem> adapter = new customAdapter(newsFeed,getActivity());
ListView newsItems =(ListView) (getActivity().findViewById(R.id.newsItems));
newsItems.setAdapter(adapter);
}
} catch (JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(newsReq);
return view;
}
private class customAdapter extends ArrayAdapter<newsItem>{
Context context;
customAdapter(List<newsItem> newsFeed, Context context) {
super(getActivity(), R.layout.item, newsFeed);
this.context = context;
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
newsItem currentItem = newsFeed.get(position);
if (convertView == null){
convertView = getActivity().getLayoutInflater().inflate(R.layout.item, parent, false);
}
ImageView newsImage = (ImageView) convertView.findViewById(R.id.leftIco);
TextView newsHeading = (TextView) convertView.findViewById(R.id.heading);
TextView newsDesc = (TextView) convertView.findViewById(R.id.desc);
newsImage.setImageResource(R.mipmap.ic_launcher);
newsHeading.setText(currentItem.getNewsHeading());
newsDesc.setText(String.valueOf((currentItem.getNewsDesc())));
return convertView;
}
}
}
Found the solution finally.
Modified MainActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.support.v7.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.lang.String;
import java.util.List;
import static android.view.LayoutInflater.from;
public class MainActivity extends AppCompatActivity {
private List<newsItem> newsFeed = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
engine();
MainActivity.this.setTitle("News");}
private void engine() {
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest newsReq = new JsonObjectRequest(Request.Method.GET,
"https://raw.githubusercontent.com/sumbganesh/temp/master/convertjson.json",
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray newsItem = response.getJSONObject("root").getJSONArray("articles");
for (int i = 0; i < newsItem.length(); i++) {
JSONObject temp = newsItem.getJSONObject(i);
String title = temp.getString("title");
String description = temp.getString("description");
String url = temp.getString("url");
String urlToImage = temp.getString("urlToImage");
newsFeed.add(new newsItem(title, description, url, urlToImage));
}
RecyclerView.Adapter adapter = new customAdapter(MainActivity.this,newsFeed);
RecyclerView newsItems =(RecyclerView) findViewById(R.id.newsItems);
LinearLayoutManager llm=new
LinearLayoutManager(MainActivity.this);
newsItems.setLayoutManager(llm);
newsItems.setAdapter(adapter);
} catch (JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(newsReq);
}
private class customAdapter extends RecyclerView.Adapter<MyViewHolder> {
private final List<newsItem> newsfeedlist;
public customAdapter(MainActivity mainActivity, List<newsItem> newsFeed) {
this.newsfeedlist= newsFeed;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().from(parent.getContext()).inflate(R.layout.item,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
newsItem items = newsfeedlist.get(position);
holder.newsImage.setImageResource(R.mipmap.ic_launcher);
holder.newsHeading.setText(items.getNewsHeading());
holder.newsDesc.setText(items.getNewsDesc());
}
#Override
public int getItemCount() {
return newsfeedlist.size();
}
}
private class MyViewHolder extends RecyclerView.ViewHolder{
public ImageView newsImage;
public TextView newsHeading;
public TextView newsDesc;
public MyViewHolder(View itemView) {
super(itemView);
newsImage = (ImageView) itemView.findViewById(R.id.leftIco);
newsHeading = (TextView) itemView.findViewById(R.id.heading);
newsDesc = (TextView) itemView.findViewById(R.id.desc);
}
}
}
Changed fragments to Activity and changed ArrayAdapter to Recycler view
Please share your customAdapter code or refer this tutorial
Listview with customadapter
Note: use recylerView in place of the listview for better performance.
Create a volley singleton class.

RecyclerView Issue

MainActivity.java
its my main java class
package com.example.shikhu.newpractice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,DisplayList.class));
}
});
}
}
DisplayList.java
package com.example.shikhu.newpractice;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class DisplayList extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dsiplay_list);
BackgroundTask backgroundTask = new BackgroundTask(DisplayList.this);
backgroundTask.execute();
}
}
BackgroundTask.java
package com.example.shikhu.newpractice;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class BackgroundTask extends AsyncTask<Void,Fruit,Void> {
String json_string = "http://192.168.1.18:8081/fruitinfo/get_fruit_details.php";
Context ctx;
Activity activity;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<Fruit> arrayList = new ArrayList<>();
public BackgroundTask(Context ctx)
{
this.ctx=ctx;
activity = (Activity)ctx;
}
#Override
protected void onPreExecute() {
recyclerView = (RecyclerView)activity.findViewById(R.id.recyclerview);
layoutManager = new LinearLayoutManager(ctx);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter = new RecyclerAdapter(arrayList);
recyclerView.setAdapter(adapter);
}
#Override
protected Void doInBackground(Void... params) {
try{
URL url = new URL(json_string);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while((line=bufferedReader.readLine())!=null)
{
stringBuilder.append(line + "\n");
}
httpURLConnection.disconnect();
String json_string = stringBuilder.toString().trim();
JSONObject jsonObject = new JSONObject(json_string);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
while (count<jsonArray.length())
{
JSONObject JO = jsonArray.getJSONObject(count);
count++;
Fruit fruit = new Fruit(JO.getString("name"),JO.getInt("calories"),JO.getDouble("fat"));
publishProgress(fruit);
}
Log.d("JSON STRING",json_string);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Fruit... values) {
arrayList.add(values[0]);
adapter.notifyDataSetChanged();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
RecyclerAdapter.java
package com.example.shikhu.newpractice;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {
private static final int TYPE_HEAD = 0;
private static final int TYPE_LIST = 1;
ArrayList<Fruit> arrayList = new ArrayList<>();
public RecyclerAdapter(ArrayList<Fruit> arrayList)
{
this.arrayList =arrayList;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEAD)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_layout,parent,false);
RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view,viewType);
return recyclerViewHolder;
}
else if (viewType == TYPE_LIST)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view,viewType);
return recyclerViewHolder;
}
return null;
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
if (holder.viewType == TYPE_LIST) {
Fruit fruit = arrayList.get(position);
holder.Name.setText(fruit.getName());
holder.Calories.setText(Integer.toString(fruit.getCalories()));
holder.Fat.setText(Double.toString(fruit.getFat()));
}
}
#Override
public int getItemCount() {
return arrayList.size();
}
public static class RecyclerViewHolder extends RecyclerView.ViewHolder
{
TextView Name,Calories,Fat;
int viewType;
public RecyclerViewHolder(View v,int viewType)
{
super(v);
if (viewType == TYPE_LIST) {
Name = (TextView) v.findViewById(R.id.name);
Calories = (TextView) v.findViewById(R.id.calories);
Fat = (TextView) v.findViewById(R.id.fat);
this.viewType = TYPE_LIST;
}else if (viewType == TYPE_HEAD)
{
this.viewType = TYPE_HEAD;
}
}
public int getItemViewType(int position)
{
if (position==0)
return TYPE_HEAD;
return TYPE_LIST;
}
}
}
Fruit.java
package com.example.shikhu.newpractice;
public class Fruit {
private String name;
private int calories;
private Double fat;
public Fruit(String name,int calories,Double fat)
{
this.setName(name);
this.setCalories(calories);
this.setFat(fat);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getCalories()
{
return calories;
}
public void setCalories(int calories)
{
this.calories=calories;
}
public Double getFat()
{
return fat;
}
public void setFat(Double fat)
{
this.fat=fat;
}
}
Row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="75dp"
android:layout_marginRight="15dp"
android:layout_marginLeft="15dp"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:textStyle="bold"
android:textSize="20dp"
android:text="Name"
android:id="#+id/name"
android:layout_weight="0.39" />
<TextView
android:layout_width="79dp"
android:layout_height="match_parent"
android:text="Calorie"
android:gravity="center_vertical"
android:textSize="20dp"
android:textStyle="bold"
android:id="#+id/calories"
android:layout_marginLeft="40dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Fat"
android:gravity="center_vertical"
android:textSize="20dp"
android:textStyle="bold"
android:id="#+id/fat"
android:layout_weight="0.15"
android:layout_marginLeft="60dp" />
</LinearLayout>
Header_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="65dp"
android:background="?attr/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:textStyle="bold"
android:textSize="20dp"
android:text="Name"
android:id="#+id/name1"
android:layout_weight="0.20"
android:textColor="#ffffff"
android:layout_marginLeft="10dp" />
<TextView
android:layout_width="79dp"
android:layout_height="match_parent"
android:text="Calorie"
android:gravity="center_vertical"
android:textSize="20dp"
android:textStyle="bold"
android:id="#+id/calories1"
android:layout_marginLeft="10dp"
android:textColor="#ffffff"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Fat"
android:gravity="center_vertical"
android:textSize="20dp"
android:textStyle="bold"
android:id="#+id/fat1"
android:layout_weight="0.15"
android:layout_marginLeft="60dp"
android:textColor="#ffffff"/>
</LinearLayout>
activity_display_list.xml
<?xml version="1.0" encoding="utf-8"?>
<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=".DisplayList">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recyclerview"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.shikhu.newpractice.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Display List"
android:id="#+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
My Output
i dont know why it is showing text of textview rather the data fetched from database
enter image description here
PhpScript
<?php
$host = "localhost";
$user = "root";
$pass = "";
$db = "fruit";
$con = mysqli_connect($host,$user,$pass,$db);
$query= "select * from fruit_details;";
$result = mysqli_query($con,$query);
$response = array();
while($row = mysqli_fetch_array($result))
{
array_push($response,array('name'=>$row[0],'calories'=>$row[1],'fat'=>$row[2 ]));
}
mysqli_close($con);
echo json_encode(array('server_response'=>$response));
?>
Your Adapter always return TYPE_HEAD i think this is wrong.
#Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEAD;
} else {
return TYPE_LIST;
}
}
BackgroundTask.Java
package com.example.shikhu.newpractice;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class BackgroundTask extends AsyncTask<Void,Fruit,Void> {
String json_string = "http://127.0.0.1:8081/fruitinfo/get_fruit_details.php";
Context ctx;
Activity activity;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<Fruit> arrayList = new ArrayList<>();
public BackgroundTask(Context ctx)
{
this.ctx=ctx;
activity = (Activity)ctx;
}
#Override
protected void onPreExecute() {
recyclerView = (RecyclerView)activity.findViewById(R.id.recyclerview);
layoutManager = new LinearLayoutManager(ctx);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter = new RecyclerAdapter(arrayList);
recyclerView.setAdapter(adapter);
}
#Override
protected Void doInBackground(Void... params) {
try{
URL url = new URL(json_string);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while((line=bufferedReader.readLine())!=null)
{
stringBuilder.append(line + "\n");
}
httpURLConnection.disconnect();
String json_string = stringBuilder.toString().trim();
JSONObject jsonObject = new JSONObject(json_string);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
while (count<jsonArray.length())
{
JSONObject JO = jsonArray.getJSONObject(count);
count++;
Fruit fruit = new Fruit(JO.getString("name"),JO.getInt("calorie"),JO.getDouble("fat"));
publishProgress(fruit);
}
Log.d("JSON STRING",json_string);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Fruit... values) {
arrayList.add(values[0]);
adapter.notifyDataSetChanged();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
RecyclerAdapter.java
package com.example.shikhu.newpractice;
import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {
private static final int TYPE_HEAD = 0;
private static final int TYPE_LIST = 1;
ArrayList<Fruit> arrayList = new ArrayList<>();
public RecyclerAdapter(ArrayList<Fruit> arrayList)
{
this.arrayList =arrayList;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEAD)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_layout,parent,false);
RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view,viewType);
return recyclerViewHolder;
}
else if (viewType == TYPE_LIST)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view,viewType);
return recyclerViewHolder;
}
return null;
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
if (holder.viewType == TYPE_LIST) {
Fruit fruit = arrayList.get(position-1);
holder.Name.setText(fruit.getName());
holder.Calories.setText(Integer.toString(fruit.getCalories()));
holder.Fat.setText(Double.toString(fruit.getFat()));
}
}
#Override
public int getItemCount() {
return arrayList.size()+1;
}
public static class RecyclerViewHolder extends RecyclerView.ViewHolder
{
TextView Name,Calories,Fat;
int viewType;
public RecyclerViewHolder(View v,int viewType)
{
super(v);
if (viewType == TYPE_LIST) {
Name = (TextView) v.findViewById(R.id.name);
Calories = (TextView) v.findViewById(R.id.calories);
Fat = (TextView) v.findViewById(R.id.fat);
this.viewType = TYPE_LIST;
}else if (viewType == TYPE_HEAD)
{
this.viewType = TYPE_HEAD;
}
}
}
#Override
public int getItemViewType(int position) {
if (position==0)
return TYPE_HEAD;
else
return TYPE_LIST;
}
}
I think you are not managing views for header in your view holder and from bind view holder it is everytime getting only header view in return; SO just debug your code and let me know that are you getting TYPE_LIST data view or not. Also make references for header view in View holder and set text to it also.
I found your problem.
Your method getItemViewType is inside your ViewHolder class. It needs to be moved to be inside your adapter class. Right now, since your adapter has no getItemViewType method, it assumes all view types are 0 (HEADER), and so nothing is being bound.
Move this method to your adapter class and all will work :)
Edit
Another option which should work for you is to stop using viewTypes all together. Since you're using the same viewHolder anyway, when you bind the view, instead of checking the viewType, check the position:
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view, TYPE_LIST);
return recyclerViewHolder;
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
if (position > 0) {
Fruit fruit = arrayList.get(position-1);
holder.Name.setText(fruit.getName());
holder.Calories.setText(Integer.toString(fruit.getCalories()));
holder.Fat.setText(Double.toString(fruit.getFat()));
} else {
holder.Name.setText("Name");
holder.Calories.setText("Calories");
holder.Fat.setText("Fat");
}
}
So now, all your view types will be of type list. This is fine, because the layout is basically identical, only the values of the TextViews changes. Instead of using viewType, simply use the position. If the position is 0, set the header fields, otherwise, use the Fruit data.
I know this is not the solution you wanted - I can't seem to find why the viewType implementation doesn't work, however, this solution should give you the result you wanted.
Hope this helps!

Recyclerview button on specific row - how to capture row id before onclicklistener?

Below is my adapter class and view code, where I am showing 2 buttons for each of the row. I have setup 2 diff listeners for each button.
New to android, I am not sure, how to get the getbarCode() (sort of row id) for the specific row button clicked? (This I want to use to set the barcode b4 I call my webservices). Currently I have hardcoded in code, I want to get it from my Books getbarCode().
Any suggestions?
BookListMyAdapter.java
package com.androidatc.customviewindrawer;
import android.app.Activity;
import android.app.ProgressDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestHandle;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.TextHttpResponseHandler;
import java.util.List;
import cz.msebera.android.httpclient.Header;
public class BookListMyAccAdapter extends RecyclerView.Adapter<BookListMyAccAdapter.PersonViewHolder> {
public static class PersonViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView title;
TextView dueDt;
final ProgressDialog progress;
// ImageView personPhoto;
public Button searchBtn, renewBtn, returnBtn;
PersonViewHolder(View itemView) {
super(itemView);
// itemView.setOnClickListener(this);
cv = (CardView) itemView.findViewById(R.id.cv);
title = (TextView) itemView.findViewById(R.id.title);
dueDt = (TextView) itemView.findViewById(R.id.dueDate);
// personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
renewBtn = (Button) itemView.findViewById(R.id.renew_button);
returnBtn = (Button) itemView.findViewById(R.id.checkin_button);
renewBtn.setOnClickListener(this); // <- This lines
returnBtn.setOnClickListener(this); // <- This lines
progress = new ProgressDialog(myActivity);
}
#Override
public void onClick(View itemView) {
switch (itemView.getId()) {
case R.id.checkin_button:
String barCode = null, patronId = null;
Log.d("TAG", "Success");
// Toast.makeText(myActivity.getApplicationContext(), "B4 calling webservice", Toast.LENGTH_LONG).show();
returnBook(barCode, patronId, progress);
break;
case R.id.renew_button:
barCode = null;
patronId = null;
Log.d("TAG", "Success");
// Toast.makeText(myActivity.getApplicationContext(), "B4 calling webservice", Toast.LENGTH_LONG).show();
renewBook(barCode, patronId, progress);
break;
}
}}
List<Books> books;
public static Activity myActivity;
BookListMyAccAdapter(List<Books> books, Activity myActivity) {
this.books = books;
this.myActivity = myActivity;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_my_acc, viewGroup, false);
PersonViewHolder pvh = new PersonViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
personViewHolder.title.setText(books.get(i).title);
personViewHolder.dueDt.setText(books.get(i).dueOn);
// personViewHolder.personPhoto.setImageResource(books.get(i).photoId);
}
#Override
public int getItemCount() {
return books.size();
}
public static void renewBook(String barCode, String patronId, final ProgressDialog progress) {
final int DEFAULT_TIMEOUT = 200000 * 1000000000;
try {
// Make RESTful webservice call using AsyncHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(DEFAULT_TIMEOUT);
progress.setMessage("Please Wait...");
progress.setIndeterminate(false);
progress.setCancelable(false);
progress.show();
RequestParams params = new RequestParams();
params.put("barcode", "B1246857");
//B1246857
//B1246855
params.put("patron", "thida");
// Toast.makeText(myActivity.getApplicationContext(), "B4 calling webservice", Toast.LENGTH_LONG).show();
client.post(" http:tron_id=2&item=1", new TextHttpResponseHandler() {
#Override
public void onSuccess(int i, Header[] headers, String response) {
Toast.makeText(myActivity.getApplicationContext(), "Response renew: " + response, Toast.LENGTH_LONG).show();
Log.d("TAG", "Success");
progress.dismiss();
}
#Override
public void onFailure(int statusCode, Header[] headers, String response, Throwable error) {
Toast.makeText(myActivity.getApplicationContext(), "Status code :" + statusCode + "errmsg : " + error.getMessage(), Toast.LENGTH_LONG).show();
// Toast.makeText(myActivity.getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet or remote server is not up and running]", Toast.LENGTH_LONG).show();
Log.d("TAG", "Failure");
progress.dismiss();
}
}
);
} catch (Exception e) {
e.printStackTrace();
//illegal argument exception
Toast.makeText(myActivity.getApplicationContext(), "Exception Caught" + e.toString(), Toast.LENGTH_LONG).show();
}
// progress.dismiss();
// Toast.makeText(myActivity.getApplicationContext(), "After calling webservice renew", Toast.LENGTH_LONG).show();
}
item_my_acc.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/title"
android:layout_gravity="left"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/dueDate"
android:layout_below="#+id/title"
/>
<Button
android:id="#+id/renew_button"
android:layout_alignParentRight="true"
android:text="#string/renew"
android:layout_below="#id/dueDate"
android:layout_width="90dp"
android:layout_height="40dp"
android:layout_gravity="right"/>
<Button
android:id="#+id/checkin_button"
android:layout_alignParentRight="true"
android:text="#string/checkin"
android:layout_below="#id/renew_button"
android:layout_width="90dp"
android:layout_height="40dp"
android:layout_gravity="right"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
RecyclerMyAccFrag.java
package com.androidatc.customviewindrawer;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.TextHttpResponseHandler;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import cz.msebera.android.httpclient.Header;
public class RecyclerMyAccFrag extends Fragment
// implements View.OnClickListener
{
public List<Books> books;
public RecyclerView rv;
public TextView formatTxt, contentTxt, TitleTxt, PublisherTxt, CreatorTxt, AvailabiltyTxt;
public Button searchBtn,renewBtn, returnBtn;
ProgressDialog progress;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.recycler_my_acc, container, false);
// renewBtn = (Button) rootView.findViewById(R.id.renew_button);
// returnBtn = (Button) rootView.findViewById(R.id.checkin_button);
// renewBtn.setOnClickListener(this);
// returnBtn.setOnClickListener(this);
String response =getArguments().getString("book_xml");
rv=(RecyclerView)rootView.findViewById(R.id.rv);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
rv.setHasFixedSize(true);
// progress = new ProgressDialog(getActivity());
readDetails(response);
initializeAdapter();
return rootView;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
public void initializeData(String[] titles, String [] dueDts, int total, String [] barCode){
books = new ArrayList<>();
for(int i = 0;i<total;i++)
{
books.add(new Books(titles[i], dueDts[i], barCode[i]));
// Toast.makeText(getActivity().getApplicationContext(), "Title : " + i +
// " " + titles[i] + " Due Date: " + dueDts[i], Toast.LENGTH_LONG).show();
}
Toast.makeText(getActivity().getApplicationContext(), "Total Number of Books Found:"
+ total , Toast.LENGTH_LONG).show();
}
public void initializeAdapter(){
BookListMyAccAdapter adapter = new BookListMyAccAdapter(books, getActivity());
rv.setAdapter(adapter);
}
Books.java
package com.androidatc.customviewindrawer;
class Books {
String title;
String dueOn;
public String getBarCode() {
return barCode;
}
public void setBarCode(String barCode) {
this.barCode = barCode;
}
// int photoId;
String barCode;
Books(String title, String dueOn, String barCode) {
this.title = title;
this.dueOn = dueOn;
this.barCode = barCode;
// this.photoId = photoId;
}
}
You need getAdapterPosition() (https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#getAdapterPosition())
And then get the access (or path the event) List<Books> books; in your adapter.
The easiest way (if you do not need your ViewHolder as static class) is making it just public class and so you will get access as the inner class of the adapter.

Categories