I'm getting the error:
RecyclerView﹕ No adapter attached; skipping layout
I checked some other answers people have given for this issue, but had no luck.
Adapter:
public class MyAdapter extends RecyclerView.Adapter<com.example.myapplication.MyAdapter.MyViewHolder> {
private Context context;
private List<HeadlineModel> headlineModelList;
public MyAdapter(Context context, List<HeadlineModel> headlineModelList) {
this.context = context;
this.headlineModelList = headlineModelList;
}
#NonNull
#Override
public com.example.myapplication.MyAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.news_item_layout,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final com.example.myapplication.MyAdapter.MyViewHolder holder, int position) {
final HeadlineModel headlineModel=headlineModelList.get(position);
holder.newTitle.setText(headlineModel.getTitle());
holder.newsDescription.setText(headlineModel.getDescription());
holder.newsDescription.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Uri uri= Uri.parse(headlineModel.getUrl());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
context.startActivity(intent);
//Log.v("SSSSSS",headlineModel.getUrl());
}
});
holder.newsName.setText(headlineModel.getName());
holder.newsTime.setText(headlineModel.getPublishedAt());
Glide.with(context).load(headlineModel.getUrlToImage())
.thumbnail(0.5f)
.into(holder.newsImage);
}
#Override
public int getItemCount() {
return headlineModelList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView newTitle;
TextView newsDescription;
TextView newsName;
TextView newsTime;
ImageView newsImage;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
newTitle=itemView.findViewById(R.id.tv_news_title);
newsDescription=itemView.findViewById(R.id.tv_news_desc);
newsName=itemView.findViewById(R.id.tv_name);
newsTime=itemView.findViewById(R.id.tv_news_date);
newsImage=itemView.findViewById(R.id.im_news_image);
}
}
}
The recycler view in onCreateView in my fragment is initialized like this:
RecyclerView recyclerView;
com.example.myapplication.MyAdapter myAdapter;
private ProgressDialog progressDialog;
List<com.example.myapplication.HeadlineModel> headlineModelList;
private static final String URL="http://newsapi.org/v2/top-headlines?country=in&apiKey=cbd46bd6a4f54fe69d0cb261dbe1a878";
public HeadlinesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootview=inflater.inflate(R.layout.fragment_headlines, container, false);
// Inflate the layout for this fragment
recyclerView=rootview.findViewById(R.id.headRecyclerView);
headlineModelList=new ArrayList<>();
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL,false));
progressDialog=new ProgressDialog(getContext(),R.style.ProgressColor);
progressDialog.setMessage("loading...");
progressDialog.show();
loadData();
return rootview;
}
loadData() function that is called
private void loadData() {
progressDialog.setMessage("Loading data...");
//progressDialog.show();
JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(Request.Method.GET, URL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
progressDialog.dismiss();
try {
JSONArray jsonArray=response.getJSONArray("articles");
for (int i=0;i<jsonArray.length();i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
String title=jsonObject.getString("title");
String desc=jsonObject.getString("description");
String url=jsonObject.getString("url");
String urlToImage=jsonObject.getString("urlToImage");
String publishedAt=jsonObject.getString("publishedAt");
JSONObject source=jsonObject.getJSONObject("source");
String name=source.getString("name");
// for formatting time and date //
String year=publishedAt.substring(0,4);
String month=publishedAt.substring(5,7);
String date=publishedAt.substring(8,10);
String hour=publishedAt.substring(11,13);
//String hour="11";
String min=publishedAt.substring(14,16);
//Log.v("XXXXXX",min);
String updatedDate=date.concat("-").concat(month).concat("-").concat(year).concat(" ");
String print="";
int convertHour= Integer.parseInt(hour);
int convertMin= Integer.parseInt(min);
if (convertHour==12) {
convertHour=12;
print="PM";
}
else if (convertHour>11&&convertMin>0){
convertHour=convertHour-12;
print="PM";
}else {
print="AM";
}
String newHour= String.valueOf(convertHour);
String updatedTime=updatedDate.concat(newHour).concat(":").concat(min).concat(" ").concat(print);
myAdapter=new com.example.myapplication.MyAdapter(getContext(),headlineModelList);
com.example.myapplication.HeadlineModel headlineModel=new com.example.myapplication.HeadlineModel(name,title,desc,url,urlToImage,updatedTime);
headlineModelList.add(headlineModel);
recyclerView.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
})
{
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
long now = System.currentTimeMillis();
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
cacheEntry.data = response.data;
cacheEntry.softTtl = softExpire;
cacheEntry.ttl = ttl;
String headerValue;
headerValue = response.headers.get("Date");
if (headerValue != null) {
cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
headerValue = response.headers.get("Last-Modified");
if (headerValue != null) {
cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
cacheEntry.responseHeaders = response.headers;
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString), cacheEntry);
} catch (UnsupportedEncodingException | JSONException e) {
return Response.error(new ParseError(e));
}
}
#Override
protected void deliverResponse(JSONObject response) {
super.deliverResponse(response);
}
#Override
public void deliverError(VolleyError error) {
super.deliverError(error);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
};
RequestQueue queue= Volley.newRequestQueue(getContext());
queue.add(jsonObjectRequest);
}
Does anyone know what I'm doing wrong?
Set the Adapter before the API call success because your API response is async and till will take time depending upon response size, network speed etc, till that time recycler view needs to be created and it is having no adapter.
You can set adaptor before calling loadData() and later when you get the list of response set the data in the adapter of your recylerview and call notify on the adapter.
myAdapter=new com.example.myapplication.MyAdapter(getContext(),headlineModelList);
recyclerView.setAdapter(myAdapter);
use it on onCreateView method and myAdapter.notifyDataSetChanged(); use it when API success
Related
i want create a fragment and have inside a recycler view for show products ...
but when i render it is show this error : RecyclerView: No adapter attached; skipping layout
below i copy my codes;
this code is for adapter class :
private ArrayList<Products> ProductsList;
private Context context;
public Adapter(ArrayList<Products> productsList, Context context) {
ProductsList = productsList;
this.context = context;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false);
return new MyHolder(v);
}
#Override
public void onBindViewHolder(MyHolder holder, final int position) {
Products products = ProductsList.get(position);
holder.txtName.setText(products.getName());
holder.txtPrice.setText("$ " + products.getPrice());
Picasso.get().load(Config.ipValue + "/images/" + products.getPhoto()).into(holder.imgV);
holder.imgV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(AnimationUtils.loadAnimation(context, android
.R.anim.slide_in_left));
}
});
}
#Override
public int getItemCount() {
return ProductsList.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView txtName;
TextView txtPrice;
ImageView imgV;
public MyHolder(View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.rowTxtProductName);
txtPrice = itemView.findViewById(R.id.rowTxtPrice);
imgV = itemView.findViewById(R.id.rowImgProduct);
}
}
and this one for web api class :
public class WebApiHandler {
Context context;
String apiLink = "";
ArrayList<Products> products = new ArrayList<>();
public WebApiHandler(Context context) {
this.context = context;
}
void apiConnect(String type) {
switch (type) {
case "getproducts": {
apiLink = Config.getProductsWebApi;
break;
}
}
ProgressDialog dialog = ProgressDialog.show(context, "Connecting...",
"please wait", false, false);
StringRequest request = new StringRequest(Request.Method.POST,
apiLink, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
dialog.dismiss();
showJson(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.dismiss();
}
});
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(request);
}
private void showJson(String response) {
products.clear();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = object.getString("id");
String name = object.getString("name");
String description = object.getString("description");
String price = object.getString("price");
String photo = object.getString("photo");
Products p = new Products(id, name, description, price, photo);
products.add(p);
}
} catch (JSONException e) {
e.printStackTrace();
}
VerticalFragment.productsArrayList = products;
IData iData = (IData) context;
iData.sendData();
}}
and my fragment code :
public class VerticalFragment extends Fragment implements IData {
RecyclerView rcVertical;
WebApiHandler webApiHandler;
static ArrayList<Products> productsArrayList = new ArrayList<>();
public VerticalFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_vertical, container, false);
rcVertical = view.findViewById(R.id.rcVertical);
webApiHandler = new WebApiHandler(getContext());
webApiHandler.apiConnect("getproducts");
rcVertical.addOnItemTouchListener(new RecyclerTouchListener(getContext(), rcVertical,
new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
ProductActivity.products = productsArrayList.get(position);
startActivity(new Intent(getContext(), ProductActivity.class));
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
#Override
public void sendData() {
Adapter adapter = new Adapter(productsArrayList, getContext());
rcVertical.setLayoutManager(new LinearLayoutManager((getContext())));
rcVertical.setItemAnimator(new DefaultItemAnimator());
rcVertical.setAdapter(adapter);
}}
i should say i create a interface and have one method i say it sendData
This is a common error when there is no adapter attached to recyclerview upon showing recyclerview. It will not cause any harm to your app, but you could avoid it by setting empty adapter without data, and later when you get your data, provide it to your adapter and notify it
Edit - Example added
Create setter for your list in adapter. After that, in your fragment make adapter global and in onCreateView make instance of your adapter and attach it to recyclerview
adapter = new Adapter(new ArrayList<>(), getContext());
rcVertical.setAdapter(adapter);
...Initialize recyclerview...
And then in your sendData interface put your loaded values in it
adapter.setData(productsArrayList);
adapter.notifyDataSetChanged();
I made an online music player with PHP code server and I have no problem fetching data in JSON format. I have a problem with the Android side where no data is shown in my recyclerview although I initialized it correctly. Please help me to find out what's wrong.
Here's my code:
MainActivity:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RequestQueue requestQueue;
Context context;
ListAdapter adapter;
LinearLayoutManager layoutManager;
List<Listening> list = new ArrayList<>();
String url = "https://www.learnhere.ir/listening.php";
AccessDataOnServer data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
requestQueue = Volley.newRequestQueue(context);
layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
adapter = new ListAdapter(list, context);
data = new AccessDataOnServer();
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
data.getData(context, list, recyclerView, url, requestQueue);
}
}
ListAdapter:
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
List<Listening> listeningList;
Context context;
public ListAdapter(List<Listening> listeningList, Context context) {
this.listeningList = listeningList;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Listening listening = listeningList.get(position);
holder.track.setText(listening.getTitle());
holder.term.setText(listening.getTerm());
Picasso.get().load(listening.getCover()).placeholder(R.mipmap.ic_launcher).into(holder.avatar);
}
#Override
public int getItemCount() {
return listeningList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
ImageView avatar;
TextView track, term;
public ViewHolder(#NonNull View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.card_view);
avatar = itemView.findViewById(R.id.avatar);
track = itemView.findViewById(R.id.track_title);
term = itemView.findViewById(R.id.term);
}
}
}
Class to get my data by help of Volley Library:
public class AccessDataOnServer extends AppCompatActivity {
RequestQueue req;
Context context;
ListAdapter adapter;
List<Listening> list1 = new ArrayList<>();
String url = "https://learnhere.ir/listening.php";
public void getData(final Context con, final List<Listening> list1, final RecyclerView recyclerView, String url, RequestQueue req
) {
this.req = req;
req = Volley.newRequestQueue(con);
this.list1 = list1;
JsonObjectRequest job = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("music");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject job = jsonArray.getJSONObject(i);
String title = job.getString("title");
String cover = job.getString("cover");
String link = job.getString("track");
String term = job.getString("term");
Listening m = new Listening();
m.setTitle(title);
m.setTerm(term);
m.setCover(cover);
m.setTrackLink(link);
list1.add(m);
}
adapter = new ListAdapter(list1, con);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
} catch (Exception e) {
Toast.makeText(con, "try error", Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(con, "not response", Toast.LENGTH_SHORT).show();
}
});
req.add(job);
}
}
My data model:
public class Listening {
private String title;
private String term;
private String cover;
private String trackLink;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTerm() {
return term;
}
public void setTerm(String term) {
this.term = term;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public String getTrackLink() {
return trackLink;
}
public void setTrackLink(String trackLink) {
this.trackLink = trackLink;
}
}
Your codes work correctly and there's no problem with them. Did you test it on emulator? Try to wipe data on emulator or test on physical device. Your problem should be solved.
I want to refresh/reload the fragment right after getting back from the activity that changed its values.
I opened an activity from my fragment
In that activity I updated some SQL that shows in the Fragment
Then I went back to the fragment using finish(); which sends me back to the fragment
I have tried using onResume() with adapter.notifyDataSetChanged(), but that crashed the app with this error:
Attempt to invoke virtual method 'void com.example.tomaspap.ItemMySerieRecyclerView.MyAdapterItemMySerie.notifyDataSetChanged()' on a null object reference
Fragment Code :
public class SeriesFragment extends Fragment {
private static final String TAG = "MySeriesFragment";
private final String URLBASIS = "https://api.themoviedb.org/3/tv/";
private final String URLAPIKEY = "?api_key=4946fe5b625b70f37a13e1fe882451a4";
private final String imagebaseurl = "http://image.tmdb.org/t/p/w500";
RecyclerView mRecyclerView;
MyAdapterItemMySerie mAdapter;
String serieid;
String watchstate;
private ArrayList<MySerieModel> models;
private RequestQueue mRequestQueue;
private JsonObjectRequest request;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_series, container, false);
models = new ArrayList<>();
mRecyclerView = v.findViewById(R.id.series_recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mAdapter = new MyAdapterItemMySerie(getContext(), models);
//mRecyclerView.setAdapter(mAdapter);
return v;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DBHelper db = new DBHelper(getContext());
Cursor cursor = db.Select_All_Serie();
models = new ArrayList<>();
cursor.moveToFirst();
if(cursor.getCount()==0){
Toast.makeText(getContext(), "NO SERIES", Toast.LENGTH_SHORT).show();
}
if(cursor.getCount() > 0){
do {
serieid = cursor.getString(cursor.getColumnIndex("serieid")).toString();
watchstate = cursor.getString(cursor.getColumnIndex("watchstate")).toString();
Integer yourrate = cursor.getInt(cursor.getColumnIndex("yourrate"));
Integer watchedeps = cursor.getInt(cursor.getColumnIndex("watchedeps"));
mRequestQueue = Volley.newRequestQueue(getContext());
parseJSON(serieid, watchstate);
models.add(new MySerieModel(serieid, watchstate, yourrate, watchedeps));
} while (cursor.moveToNext());
}
// Toast.makeText(getContext(), String.valueOf(models.size()), Toast.LENGTH_SHORT).show();
}
private void parseJSON(final String serieid, final String watchstate){
String url = URLBASIS + serieid + URLAPIKEY;
request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String title = (response.getString("name"));
String nextepfinal = "";
try {
JSONObject jsonArraynextep = (response.getJSONObject("next_episode_to_air"));
nextepfinal = jsonArraynextep.getString("air_date");
}catch(JSONException e){}
String state = (response.getString("status"));
// String serieid = (response.getString("id"));
String imageurl = (response.getString("poster_path"));
String image = imagebaseurl + imageurl;
MySerieModel serie = new MySerieModel(title, nextepfinal, state, watchstate, serieid, image);
models.add(serie);
} catch (JSONException e) {
e.printStackTrace();
return;
}
mAdapter = new MyAdapterItemMySerie(getContext(), models);
mRecyclerView.setAdapter(mAdapter);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
#Override
public void onResume()
{
super.onResume();
models.clear();
mAdapter.notifyDataSetChanged();
}
Thank you for the help.
your list loading methods are scattered and am sure its why they care confusing you
I would suggest you create a method eg.updateUI() and put all of them in one place then you can call this when ever you want to update the UI like the onCreate() and onResume() methods
Also its good practice to handle you list items in a singleton so that you can access them any where in you app
ModelsListFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
updateUI()
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
public void updateUI() {
ModelSingleton modelSingleton = Model.get(getActivity());
List<Model> models= modelSingleton.getModels();
if (mAdapter == null) {
mAdapter = new MyAdapterItemMySerie(getContext(), models);
mRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.setModels(models);
mAdapter.notifyDataSetChanged();
}
updateSubtitle();
}
....
i just want to leave the message if the List from Json is empty...so how should i do it...getting lots of conflits at recyclerview
A simple {#link Fragment} subclass.
public class TodayFragment extends Fragment implements ViewPager.OnPageChangeListener {
public static final String URL_DATA =Url.GET_TODAY_UPDATE;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
String currentDate="2017-06-29";
private List<TodayList> listViews;
private TextView totalPaidFees;
public TodayFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/mm/dd");
loadRecyclerViewData();
return view;
}
private void loadRecyclerViewData() {
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Loading...");
progressDialog.show();
SingletoneRequst.q(getContext()).add(new StringRequest(Request.Method.GET, URL_DATA+currentDate , new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
Log.i("#url_T","url--"+URL_DATA);
Log.i("#today", "Json--"+response.toString());
Gson gson = new Gson();
TodayFees list = (gson.fromJson(response, TodayFees.class));
List<TodayList> lists = list.getTodayList();
for (TodayList todayList : lists) {
Log.i("today", "" + todayList);
}
totalPaidFees.setText(list.getTotalFees().toString());
adapter = new Adapter_TodayFees(lists, getContext());
recyclerView.setAdapter(adapter);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getActivity(), "Network problem!! Check your internet connection", Toast.LENGTH_LONG).show();
}
}));
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
Do like that...
List<TodayList> lists = list.getTodayList();
if(lists!=null && lists.size>0){
for (TodayList todayList : lists) {
Log.i("today", "" + todayList);
}
totalPaidFees.setText(list.getTotalFees().toString());
adapter = new Adapter_TodayFees(lists, getContext());
recyclerView.setAdapter(adapter);
}
else{
//Show the message here
}
Just check if the Todayfees List has any data. If yes then set the adapter:
if(list != null){
if(list.size() > 0){
totalPaidFees.setText(list.getTotalFees().toString());
adapter = new Adapter_TodayFees(lists, getContext());
recyclerView.setAdapter(adapter);
}
else{
Toast.makeText(getActivity(), "Data couldn't be fetched properly!", Toast.LENGTH_LONG).show();
}
}
Hope it helps.
I am creating an app where a list of hotels will be shown, all the data is coming from MySQL using JSON and PHP, I created the custom list view by extending the base adapter to a custom one, but I am not able to implement a OnItemClickListener for the listview, as i want to show the Hotel Name of that row in Toast whenever the user clicks on a row of list view. I tried various example available on internet, but i just doesn't work.
Adapter
public class CustomListAdapterHotel extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<WorldsBillionaires> billionairesItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapterHotel(Activity activity, List<WorldsBillionaires> billionairesItems) {
this.activity = activity;
this.billionairesItems = billionairesItems;
}
#Override
public int getCount() {
return billionairesItems.size();
}
#Override
public Object getItem(int location) {
return billionairesItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_hotel, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
//NetworkImageView thumbNail = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView hotel_name = (TextView) convertView.findViewById(R.id.hotel_name);
TextView zone = (TextView) convertView.findViewById(R.id.zone);
TextView contact_person = (TextView) convertView.findViewById(R.id.contact_person);
TextView contact_number = (TextView) convertView.findViewById(R.id.contact_number);
TextView btc_direct = (TextView) convertView.findViewById(R.id.btcdirect);
// getting billionaires data for the row
WorldsBillionaires m = billionairesItems.get(position);
// name
hotel_name.setText(String.valueOf(m.getHotel_Name()));
zone.setText(String.valueOf(m.getHotel_Zone()));
contact_person.setText(String.valueOf(m.getContact_Person()));
contact_number.setText(String.valueOf(m.getContact_Number()));
btc_direct.setText(String.valueOf(m.getBtc_Direct()));
return convertView;
}
}
Model
public class WorldsBillionaires {
private String hotel_name,hotel_zone,contact_person,contact_number,btc_direct;
public WorldsBillionaires(String hotel_name, String hotel_zone, String contact_person, String contact_number, String btc_direct) {
this.hotel_name=hotel_name;
this.hotel_zone=hotel_zone;
this.contact_person=contact_person;
this.contact_number=contact_number;
this.btc_direct=btc_direct;
}
public WorldsBillionaires() {
}
public String getZone() {
return zone;
}
public void setZone(String zone) {
this.zone = zone;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
public String getHotel_Name() {
return hotel_name;
}
public void setHotel_Name(String hotel_name) {
this.hotel_name = hotel_name;
}
public String getHotel_Zone() {
return hotel_zone;
}
public void setHotel_Zone(String hotel_zone) {
this.hotel_zone = hotel_zone;
}
public String getContact_Person() {
return contact_person;
}
public void setContact_Person(String contact_person) {
this.contact_person = contact_person;
}
public String getContact_Number() {
return contact_number;
}
public void setContact_Number(String contact_number) {
this.contact_number = contact_number;
}
public String getBtc_Direct() {
return btc_direct;
}
public void setBtc_Direct(String btc_direct) {
this.btc_direct = btc_direct;
}
}
Main Activity
public class ShowHotel extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
// Billionaires json url
private ProgressDialog pDialog;
private List<WorldsBillionaires> worldsBillionairesList = new ArrayList<WorldsBillionaires>();
private ListView listView;
private CustomListAdapterHotel adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_hotel);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapterHotel(this, worldsBillionairesList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest billionaireReq = new JsonArrayRequest("http://192.168.247.1/AdminBihar/getHotel.php?zone="+methods.zone,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
WorldsBillionaires worldsBillionaires = new WorldsBillionaires();
worldsBillionaires.setHotel_Name(obj.getString("hotel_name"));
worldsBillionaires.setThumbnailUrl(obj.getString("image"));
worldsBillionaires.setHotel_Zone(obj.getString("zone"));
worldsBillionaires.setContact_Person(obj.getString("contact_person"));
worldsBillionaires.setContact_Number(obj.getString("contact_number"));
worldsBillionaires.setBtc_Direct(obj.getString("btc_direct"));
// adding Billionaire to worldsBillionaires array
worldsBillionairesList.add(worldsBillionaires);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(billionaireReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
so after you get json data, in activity that shows your list do something like this:
public class DisplayListView extends AppCompatActivity {
ListView listView;
protected void onCreate(){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_list_view);
listView = (ListView) findViewById(R.id.listview);
hotelAdapter = new CustomListAdapterHotel (this, R.layout.row_layout);
listView.setAdapter(hotelAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Model stuff = (Model) hotelAdapter.getItem(position);
String hotelName = stuff.getHotel_Name();
Toast.makeText(getApplicationContext(), hotelName, Toast.LENGTH_SHORT).show();
}
});
there, this worked for me :)