I have an issue where my recyclerview adds new items at the end, whereas I want the latest items at the top upon user refresh. I've been scratching around all over the net and it essentially boils down to adding setreverseLayout or setStackFromEnd. This gives other complications such as the recycler view not scrolling to the top to the latest item.
I then had a thought of maybe ordering my data list by a specific value and then it should return it as I want it. Can this be done and would it resolve my issue? I want to sort it by value adopt_rownum desc.
My Custom Adapter
package com.example.admin.paws;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
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.bumptech.glide.Glide;
import java.util.List;
/**
* Created by admin on 9/16/2016.
*/
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public Context context;
public List<MyData> my_data;
public CustomAdapter(Context context, List<MyData> my_data) {
this.context = context;
this.my_data = my_data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardnew,parent,false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String name = my_data.get(position).getName();
String age = my_data.get(position).getAge();
String gender = my_data.get(position).getGender();
String SubstAge = age.substring(0,age.indexOf("(") -1);
String NameAgeGender = name + ", " + SubstAge + ", " + gender;
holder.about.setText(my_data.get(position).getAbout());
holder.NameAgeGender.setText(NameAgeGender);
Glide.with(context).load(my_data.get(position).getPhoto_path()).into(holder.photo_path);
//activity_card_details vars
// final String about = my_data.get(position).getAbout();
final String adoptId = my_data.get(position).getId()+"";
final String photo_path_dtls = my_data.get(position).getPhoto_path();
final String listedDate = my_data.get(position).getDatetime_listed();
final String status = my_data.get(position).getStatus();
final String breed = my_data.get(position).getBreed();
final String source = my_data.get(position).getSource();
final String contact_info = my_data.get(position).getContact_info();
final String suburb = my_data.get(position).getSuburb();
final String city = my_data.get(position).getCity();
final String province = my_data.get(position).getProvince();
final String concat_location = suburb + ", " + city + ", " + province;
final String viewCounter = my_data.get(position).getViewCounter()+"";
//When click on photo
holder.photo_path.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context,CardDetailsActivity.class);
intent.putExtra("listedDate",listedDate);
intent.putExtra("adoptId",adoptId);
// intent.putExtra("about",about);
intent.putExtra("status",status);
intent.putExtra("breed",breed);
intent.putExtra("source",source);
intent.putExtra("contactinfo",contact_info);
intent.putExtra("location",concat_location);
intent.putExtra("photo_path_dtls",photo_path_dtls);
intent.putExtra("viewCounter",viewCounter);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return my_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
{
public TextView NameAgeGender;
public ImageView photo_path;
public TextView about;
private ViewHolder(View itemView) {
super(itemView);
about = (TextView) itemView.findViewById(R.id.about);
NameAgeGender = (TextView) itemView.findViewById(R.id.tvNameAgeGender);
// NameAgeGender.setTextColor(Color.parseColor("#9C9393"));
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Lato-Medium.ttf");
NameAgeGender.setTypeface(typeface);
//NameAgeGender.setBackgroundColor(Color.parseColor("#F35959"));
photo_path = (ImageView) itemView.findViewById(R.id.photo_path);
}
}
}
My DataList
package com.example.admin.paws;
public class MyData {
//the must be in the same order of the select column order
public int adopt_rownum
,viewCounter
,adopt_id;
private String
name
,type
,breed
,age
,gender
,size
,about
,photo_path
,source
,contact_info
,suburb
,city
,province
,datetime_listed
,status;
public MyData(
int adopt_rownum,
int viewCounter,
int adopt_id,
String name,
String type,
String breed,
String age,
String gender,
String size,
String about,
String photo_path,
String source,
String contact_info,
String suburb,
String city,
String province,
String datetime_listed,
String status)
{
this.adopt_rownum = adopt_rownum;
this.viewCounter = viewCounter;
this.adopt_id = adopt_id;
this.name = name;
this.type = type;
this.breed = breed;
this.age = age;
this.gender = gender;
this.size = size;
this.about = about;
this.photo_path = photo_path;
this.source = source;
this.contact_info = contact_info;
this.suburb = suburb;
this.city = city;
this.province = province;
this.datetime_listed = datetime_listed;
this.status = status;
}
//adopt_rownum used for filtering the records.
public int getAdopt_rownum() {
return adopt_rownum;
}
//viewcounter
public int getViewCounter() {
return viewCounter;
}
//adopt_id
public int getId() {
return adopt_id;
}
public void setId(int adopt_id) {
this.adopt_id = adopt_id;
}
//name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//type
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
//breed
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
//age
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
//gender
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.age = gender;
}
//size
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
//about
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
//photo path
public String getPhoto_path() {
return photo_path;
}
public void setPhoto_path(String photo_path) {
this.photo_path = photo_path;
}
//source
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
//contact_info
public String getContact_info() {
return contact_info;
}
public void setContact_info(String contact_info) {
this.contact_info = contact_info;
}
//suburb
public String getSuburb() {
return suburb;
}
public void setSuburb(String suburb) {
this.contact_info = suburb;
}
//city
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
//province
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
//datetime_listed
public String getDatetime_listed() {
return datetime_listed;
}
public void setDatetime_listed(String datetime_listed) {
this.datetime_listed = datetime_listed;
}
//status
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
The fragment that displays the results. Another question on the side, inside this fragment for load_data_from_server its giving me a warning that "This Async task should be static or leaks might occur". I have no idea what this means since I'm completely new to JAVA.
package com.example.admin.paws;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
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.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link feedFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link feedFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class feedFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public Activity FragActivity;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private List<MyData> data_list;
private CustomAdapter adapter;
RecyclerView recyclerView;
public String EndOfFeed;
private OnFragmentInteractionListener mListener;
public feedFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment fragment_feed.
*/
// TODO: Rename and change types and number of parameters
public static feedFragment newInstance(String param1, String param2) {
feedFragment fragment = new feedFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
final GridLayoutManager gridLayoutManager;
final SwipeRefreshLayout swipeRefreshLayout = rootView.findViewById(R.id.feedRefresh);
TextView tvEndOfFeed = rootView.findViewById(R.id.tvEndOfFeed);
tvEndOfFeed.setText(EndOfFeed);
//recycler view
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
data_list = new ArrayList<>();
load_data_from_server(0, "getFeed.php");
gridLayoutManager = new GridLayoutManager(getActivity(), 1); //2 nr of cards next to each other
recyclerView.setLayoutManager(gridLayoutManager);
//gridLayoutManager.setReverseLayout(true);
adapter = new CustomAdapter(getActivity(), data_list);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size() - 1) {
load_data_from_server(data_list.get(data_list.size() - 1).getAdopt_rownum(), "getFeed.php");
}
}
});
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
//this works but issue with the ordering of the adoptrownum
load_data_from_server(data_list.get(data_list.size() -1).getAdopt_rownum(), "refreshFeed.php");
swipeRefreshLayout.setRefreshing(false);
}
});
return rootView;
}
private void load_data_from_server(final int adopt_id, final String phpScript) {
AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {
#Override
protected Void doInBackground(Integer... integers) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.0.2.2/app_scripts/"+phpScript+"?adopt_rownum="+integers[0])
.build();
try {
Response response = client.newCall(request).execute();
JSONArray array = new JSONArray(response.body().string());
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
MyData data = new MyData(
object.getInt("ADOPT_ROWNUM"),
object.getInt("VIEWCOUNTER"),
object.getInt("ADOPT_ID"),
object.getString("NAME"),
object.getString("TYPE"),
object.getString("BREED"),
object.getString("AGE"),
object.getString("GENDER"),
object.getString("SIZE"),
object.getString("ABOUT"),
object.getString("PHOTO_PATH"),
object.getString("SOURCE"),
object.getString("CONTACT_INFO"),
object.getString("SUBURB"),
object.getString("CITY"),
object.getString("PROVINCE"),
object.getString("DATETIME_LISTED"),
object.getString("STATUS")
);
data_list.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
System.out.println("End of content"+e);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged();
}
};
task.execute(adopt_id);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
I added the Comparator as instructed below but the output is a bit weird...
public class MyComparator implements Comparator<MyData > {
#Override
public int compare(final MyData o1, final MyData o2) {
Log.d("APP", "compare Starting... ");
Integer val1 = o1.getAdopt_rownum();
Log.d("APP", "compare val1... "+val1);
Integer val2 = o2.getAdopt_rownum();
Log.d("APP", "compare val1... "+val2);
Log.d("APP", "compare val1 and val2 ="+val1.compareTo(val2));
return val1.compareTo(val2);
}
}
output
compare Starting...
compare val1... 2
compare val2... 1
compare val1 and val2 =1
...
compare Starting...
compare val1... 14
compare val2... 15
compare val2 and val2 =1
Below is how i implemented it in my fragment
private void load_data_from_server(final int adopt_id, final String phpScript) {
AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {
#Override
protected Void doInBackground(Integer... integers) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.0.2.2/app_scripts/"+phpScript+"?adopt_rownum="+integers[0])
.build();
try {
Response response = client.newCall(request).execute();
JSONArray array = new JSONArray(response.body().string());
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
MyData data = new MyData(
object.getInt("ADOPT_ROWNUM"),
object.getInt("VIEWCOUNTER"),
object.getInt("ADOPT_ID"),
object.getString("NAME"),
object.getString("TYPE"),
object.getString("BREED"),
object.getString("AGE"),
object.getString("GENDER"),
object.getString("SIZE"),
object.getString("ABOUT"),
object.getString("PHOTO_PATH"),
object.getString("SOURCE"),
object.getString("CONTACT_INFO"),
object.getString("SUBURB"),
object.getString("CITY"),
object.getString("PROVINCE"),
object.getString("DATETIME_LISTED"),
object.getString("STATUS")
);
data_list.add(data);
**Collections.sort(data_list,new MyComparator());**
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
//System.out.println("End of content"+e);
EndOfFeed = e+"";
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged();
}
};
task.execute(adopt_id);
}
You can sort list by a property using the following code:
Collections.sort(myList, new MyComparator());
public static class MyComparator implements Comparator<MyData > {
#Override
public int compare(final MyData o1, final MyData o2) {
return o1.getAdoptRownum().compareTo(o2.getAdoptRownum());
}
}
I usually declare comparators inside the relevant POJO class. Then you can call Collections.sort whenever you refresh your data.
Related
I want to make a videoplay app, i am getting the video folders and showing them in the recyclerview , i am able to show the video folders but not able to show the size of the video folders . i created a model class called MediaFiles and set an adapter for theRecyclerView called VideoFolderAdapter. If you can help me , then please help me.
This is my videofolderadapter code
package com.fun.rapidplayer;
import static java.security.AccessController.getContext;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.os.FileUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class VideoFoldersAdapter extends RecyclerView.Adapter<VideoFoldersAdapter.ViewHolder> {
private ArrayList<MediaFiles> mediaFiles;
private ArrayList<String> folderPath;
private Context context;
public VideoFoldersAdapter(ArrayList<MediaFiles> mediaFiles, ArrayList<String> folderPath, Context context) {
this.mediaFiles = mediaFiles;
this.folderPath = folderPath;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.floder_item,parent,false);
return new ViewHolder(view);
}
#NonNull
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
int indexPath = folderPath.get(position).lastIndexOf ("/");
String nameOfFolder = folderPath.get(position).substring(indexPath+1);
holder.folderName.setText(nameOfFolder);
holder.nooffiles.setText(noOffiles(folderPath.get(position))+" Videos");
String size = how to get please help
}
#Override
public int getItemCount() {
return folderPath.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView folderName;
TextView nooffiles;
TextView foldersize;
CardView cardview1,cardview2;
public ViewHolder(#NonNull View itemView) {
super(itemView);
folderName = itemView.findViewById(R.id.folderName);
nooffiles = itemView.findViewById(R.id.nooffiles);
foldersize = itemView.findViewById(R.id.foldersize);
cardview1 = itemView.findViewById(R.id.cardview1);
cardview2 = itemView.findViewById(R.id.cardview2);
}
}
int noOffiles(String folder_name) {
int files_no = 0;
for (MediaFiles mediaFiles : mediaFiles) {
if (mediaFiles.getPath().substring(0, mediaFiles.getPath().lastIndexOf("/"))
.endsWith(folder_name)) {
files_no++;
}
}
return files_no;
}
public void _shapeRadius(final View _v, final String _color, final double _radius) {
android.graphics.drawable.GradientDrawable shape = new android.graphics.drawable.GradientDrawable();
shape.setShape(android.graphics.drawable.GradientDrawable.RECTANGLE);
shape.setCornerRadius((int)_radius);
shape.setColor(Color.parseColor(_color));
_v.setBackgroundDrawable(shape);
}
private String bytesIntoHumanReadable(long bytes) {
long kilobyte = 1024;
long megabyte = kilobyte * 1024;
long gigabyte = megabyte * 1024;
long terabyte = gigabyte * 1024;
if ((bytes >= 0) && (bytes < kilobyte)) {
return bytes + " B";
} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
return (bytes / kilobyte) + " KB";
} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
return (bytes / megabyte) + " MB";
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
return (bytes / gigabyte) + " GB";
} else if (bytes >= terabyte) {
return (bytes / terabyte) + " TB";
} else {
return bytes + " Bytes";
}
}
}
This is my Meadiafiles Modelclass Code
package com.fun.rapidplayer;
public class MediaFiles {
public String id;
public String title;
public String displayNam;
public String size;
public String duration;
public String path;
public String datAdded;
public MediaFiles(String id, String title, String displayNam, String size, String duration, String path, String datAdded) {
this.id = id;
this.title = title;
this.displayNam = displayNam;
this.size = size;
this.duration = duration;
this.path = path;
this.datAdded = datAdded;
}
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 getDisplayNam() {
return displayNam;
}
public void setDisplayNam(String displayNam) {
this.displayNam = displayNam;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getDatAdded() {
return datAdded;
}
public void setDatAdded(String datAdded) {
this.datAdded = datAdded;
}
}
And this is my MainActivity Code
package com.fun.rapidplayer;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ArrayList<MediaFiles> mediaFiles = new ArrayList<>();
private ArrayList<String> allfolderList = new ArrayList<>();
RecyclerView recyclerview1;
VideoFoldersAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerview1 = findViewById(R.id.recyclerview1);
showfolder();
}
private void showfolder() {
mediaFiles = fetchMedeia();
adapter = new VideoFoldersAdapter(mediaFiles, allfolderList, this);
recyclerview1.setAdapter(adapter);
recyclerview1.setLayoutManager(new LinearLayoutManager(this,
recyclerview1.VERTICAL, false));
adapter.notifyDataSetChanged();
}
public ArrayList<MediaFiles> fetchMedeia() {
ArrayList<MediaFiles> mediaFilesArrayList = new ArrayList<>();
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToNext()) {
do {
String id = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media._ID));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));
String displayName = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME));
String size = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.SIZE));
String duration = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DURATION));
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));
String dateAdded = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED));
MediaFiles mediaFiles = new MediaFiles(id, title, displayName, size, duration, path, dateAdded);
int index = path.lastIndexOf("/");
String substring = path.substring(0, index);
if (!allfolderList.contains(substring)) {
allfolderList.add(substring);
}
mediaFilesArrayList.add(mediaFiles);
} while (cursor.moveToNext());
}
return mediaFilesArrayList;
}
}
anyone can please help.
how are you, I hope you are well
- I am using Room library to store products in RecyclerView.
- When using SearchView to search for a product by its name, the product name appears only when typing the first letter (that is, SearchView only interacts with the first letter of the product name).
Also, when you delete the letter, the complete list of products does not appear again.
Please help me find the error in the code
Warm regards, artist
dependencies
implementation "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
//noinspection LifecycleAnnotationProcessorWithJava8
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
ProductEntry
#Entity(tableName = "product")
public class ProductEntry {
#PrimaryKey(autoGenerate = true)
private int id;
#ColumnInfo(name = "productName")
private final String productName;
private final String productBarcode, productQuantity
, productPurchasingPrice, productSellingPrice, productDescription, productCategory;
#Ignore
public ProductEntry(String productName, String productBarcode, String productQuantity
, String productPurchasingPrice, String productSellingPrice, String productDescription, String productCategory) {
this.productName = productName;
this.productBarcode = productBarcode;
this.productQuantity = productQuantity;
this.productPurchasingPrice = productPurchasingPrice;
this.productSellingPrice = productSellingPrice;
this.productDescription = productDescription;
this.productCategory = productCategory;
}
public ProductEntry(int id, String productName, String productBarcode, String productQuantity
, String productPurchasingPrice, String productSellingPrice, String productDescription, String productCategory) {
this.id = id;
this.productName = productName;
this.productBarcode = productBarcode;
this.productQuantity = productQuantity;
this.productPurchasingPrice = productPurchasingPrice;
this.productSellingPrice = productSellingPrice;
this.productDescription = productDescription;
this.productCategory = productCategory;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public String getProductBarcode() {
return productBarcode;
}
public String getProductQuantity() {
return productQuantity;
}
public String getProductPurchasingPrice() {
return productPurchasingPrice;
}
public String getProductSellingPrice() {
return productSellingPrice;
}
public String getProductDescription() {
return productDescription;
}
public String getProductCategory() {
return productCategory;
}
}
ProductDao
#Dao
public interface ProductDao {
#Query("SELECT * FROM product ORDER BY id")
LiveData<List<ProductEntry>> loadAllTasks();
#Query("SELECT * FROM product WHERE id = :id")
LiveData<ProductEntry> loadTaskById(int id);
#Query("SELECT * FROM product WHERE productName LIKE :findProductName")
LiveData<List<ProductEntry>> findProduct(String findProductName);
#Insert
void insertTask(ProductEntry productEntry);
#Update(onConflict = OnConflictStrategy.REPLACE)
void updateTask(ProductEntry productEntry);
#Delete
void deleteTask(ProductEntry productEntry);
}
FindProductViewModel
public class FindProductViewModel extends ViewModel {
private final LiveData<List<ProductEntry>> findProduct;
public FindProductViewModel(AppDatabase database, String searchQuery) {
findProduct = database.productDao().findProduct(searchQuery);
}
public LiveData<List<ProductEntry>> getFindProduct() {
return findProduct;
}
}
FindProductViewModelFactory
public class FindProductViewModelFactory extends ViewModelProvider.NewInstanceFactory {
private final AppDatabase mDb;
private final String mProductQuery;
public FindProductViewModelFactory(AppDatabase database, String productQuery) {
mDb = database;
mProductQuery = productQuery;
}
#NonNull
#Override
public <T extends ViewModel> T create(#NonNull Class<T> modelClass) {
//noinspection unchecked
return (T) new FindProductViewModel(mDb, mProductQuery);
}
}
ProductsActivity
public class ProductsActivity extends AppCompatActivity implements ProductAdapter.ItemClickListener {
private FloatingActionButton fabAddProduct;
private RecyclerView recyclerView;
private ProductAdapter productAdapter;
private AppDatabase mDb;
private View emptyView;
private SearchView productSearchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_products);
initView();
setupViewModel();
setupRecycleView();
fabAddProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent addProductIntent = new Intent(ProductsActivity.this, AddProductActivity.class);
startActivity(addProductIntent);
}
});
productSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
getItemFromDb(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
getItemFromDb(newText);
// productAdapter.getFilter().filter(newText);
return false;
}
});
}
private void getItemFromDb(String query) {
String searchText = "%" + query + "%";
FindProductViewModelFactory factory = new FindProductViewModelFactory(mDb, searchText);
final FindProductViewModel viewModel = ViewModelProviders
.of(ProductsActivity.this, (ViewModelProvider.Factory) factory)
.get(FindProductViewModel.class);
viewModel.getFindProduct().observe(this, new Observer<List<ProductEntry>>() {
#Override
public void onChanged(#Nullable List<ProductEntry> productEntries) {
viewModel.getFindProduct().removeObserver(this);
productAdapter.setProductEntries(productEntries);
}
});
}
private void initView() {
emptyView = findViewById(R.id.empty_view);
fabAddProduct = findViewById(R.id.fabAddProducts);
recyclerView = findViewById(R.id.recyclerViewProducts);
productSearchView = findViewById(R.id.productSearchView);
}
private void setupRecycleView() {
mDb = AppDatabase.getInstance(getApplicationContext());
productAdapter = new ProductAdapter(this, this, mDb);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(productAdapter);
}
private void setupViewModel() {
MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.getProducts().observe(this, new Observer<List<ProductEntry>>() {
#Override
public void onChanged(#Nullable List<ProductEntry> productEntries) {
productAdapter.setProductEntries(productEntries);
if (productAdapter.getItemCount() == 0) {
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
productSearchView.setVisibility(View.GONE);
} else {
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
productSearchView.setVisibility(View.VISIBLE);
}
}
});
}
#Override
public void onItemClickListener(int itemId) {
Intent intent = new Intent(ProductsActivity.this, AddProductActivity.class);
intent.putExtra(AddProductActivity.EXTRA_PRODUCT_ID, itemId);
startActivity(intent);
}
}
To give you the simple answer, the reason you are getting only the first update is the line with viewModel.getFindProduct().removeObserver(this);
Thank you very much
I solved the problem by adding the following code
package com.artist.bookkeeper.activities;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.artist.bookkeeper.database.entry.ProductEntry;
import com.artist.bookkeeper.viewmodel.MainViewModel;
import com.artist.bookkeeper.adapters.ProductsAdapter;
import com.artist.bookkeeper.R;
import com.artist.bookkeeper.database.AppDatabase;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.List;
public class ProductStoreActivity extends AppCompatActivity implements ProductsAdapter.ItemClickListener {
private FloatingActionButton addProductFab;
private RecyclerView productsRv;
private ProductsAdapter productsAdapter;
private AppDatabase appDatabase;
private View productsEmptyView;
private SearchView productsSv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_store);
initProductView();
setupProductViewModel();
setupProductRecycleView();
addProductFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(ProductStoreActivity.this, AddProductActivity.class));
}
});
productsSv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
setupProductViewModel();
productsFilter(newText);
return true;
}
});
}
private void productsFilter(String text) {
ArrayList<ProductEntry> productsList = new ArrayList<>();
for (ProductEntry product : productsAdapter.getProductEntries()) {
if (product.getProductName().toLowerCase().contains(text.toLowerCase())) {
productsList.add(product);
}
}
if (productsList.isEmpty()) {
Toast.makeText(this, getString(R.string.no_product), Toast.LENGTH_SHORT).show();
} else {
productsAdapter.setProductEntries(productsList);
}
}
private void initProductView() {
productsEmptyView = findViewById(R.id.productEmptyView);
addProductFab = findViewById(R.id.addProductFab);
productsRv = findViewById(R.id.productRv);
productsSv = findViewById(R.id.productSv);
}
private void setupProductRecycleView() {
appDatabase = AppDatabase.getInstance(getApplicationContext());
productsAdapter = new ProductsAdapter(this, this, appDatabase);
productsRv.setHasFixedSize(true);
productsRv.setLayoutManager(new LinearLayoutManager(this));
productsRv.setAdapter(productsAdapter);
}
private void setupProductViewModel() {
MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
mainViewModel.getListProductsLiveData().observe(this, new Observer<List<ProductEntry>>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onChanged(#Nullable List<ProductEntry> productEntries) {
productsAdapter.setProductEntries(productEntries);
productsAdapter.notifyDataSetChanged();
if (productsAdapter.getItemCount() == 0) {
productsRv.setVisibility(View.GONE);
productsEmptyView.setVisibility(View.VISIBLE);
productsSv.setVisibility(View.GONE);
} else {
productsRv.setVisibility(View.VISIBLE);
productsEmptyView.setVisibility(View.GONE);
productsSv.setVisibility(View.VISIBLE);
}
}
});
}
#Override
public void onItemClickListener(int productId, String productName) {
Intent intent = new Intent(ProductStoreActivity.this, ProductDetailsActivity.class);
intent.putExtra("productId", productId);
intent.putExtra("productName", productName);
startActivity(intent);
}
}
I try to get data from my Api, I can get data and convert it into an object class I created and show it but I can't store all objects instances in an list. Someone knows ?
I tried to add every element I got in a List then try to get elements from it after but doesn't work, the list stays empty.
This is what my API returns :
{"_id":"60683c5bcdfcb74689bc8382","questionId":3,"question":"Question 3","choices":"1-/-2-/-3-/-4","category":"Other","difficulty":"Easy"}
This is my "ApiTest activity" :
package com.jojo.jojozquizz;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
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 com.jojo.jojozquizz.model.Question;
import com.jojo.jojozquizz.model.QuestionBank;
import com.jojo.jojozquizz.tools.APIListener;
import org.json.JSONException;
import org.json.JSONObject;
public class ApiTests extends AppCompatActivity implements APIListener {
private TextView text;
public static final String TAG = "MyTag";
private QuestionBank mQuestionBank;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_api_tests);
mQuestionBank = new QuestionBank();
text = findViewById(R.id.api_text);
String url = "https://nextfor.studio/questions/test";
getQuestionFromApi(url);
}
private void getQuestionFromApi(String url) {
APIListener listener = this;
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, "onResponse: " + response.toString());
Question question = new Question();
question.setId(response.getInt("questionId"));
question.setQuestion(response.getString("question"));
question.setChoices(response.getString("choices"));
question.setCategory(response.getString("category"));
question.setDifficulty(response.getString("difficulty"));
listener.questionReceived(question);
} catch (JSONException e) {
Log.i(TAG, e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse: " + error.getMessage());
}
});
requestQueue.add(jsonObjectRequest);
}
#Override
public void questionReceived(Question q) {
mQuestionBank.addQuestion(q);
}
}
Question class :
package com.jojo.jojozquizz.model;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import java.io.Serializable;
import java.util.List;
#Entity(tableName = "questions")
public class Question implements Serializable {
#PrimaryKey()
#ColumnInfo(name = "id")
private long id;
#ColumnInfo(name = "question")
private String mQuestion;
#Ignore
private List<String> mChoiceList;
#ColumnInfo(name = "choices")
private String mChoices;
#ColumnInfo(name = "answer_index")
private int mAnswerIndex;
#ColumnInfo(name = "categorie")
private String mCategory;
#Ignore
private String mTrueAnswer;
#ColumnInfo(name = "difficulty")
private String mDifficulty;
public Question() {
}
public Question(int id, String mQuestion, List<String> mChoiceList, String mCategorie, String mDifficulty) {
this.id = id;
this.mQuestion = mQuestion;
this.mChoices = mChoiceList.get(0) + "-/-" + mChoiceList.get(1) + "-/-" + mChoiceList.get(2) + "-/-" + mChoiceList.get(3);
this.mAnswerIndex = 0;
this.mCategory = mCategorie;
this.mDifficulty = mDifficulty;
}
public Question(String mQuestion, List<String> mChoiceList, String mCategorie, String mDifficulty) {
this.mQuestion = mQuestion;
this.mChoices = mChoiceList.get(0) + "-/-" + mChoiceList.get(1) + "-/-" + mChoiceList.get(2) + "-/-" + mChoiceList.get(3);
this.mAnswerIndex = 0;
this.mCategory = mCategorie;
this.mDifficulty = mDifficulty;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getQuestion() {
return mQuestion;
}
public void setQuestion(String question) {
mQuestion = question;
}
public List<String> getChoiceList() {
return mChoiceList;
}
public void setChoiceList(List<String> choiceList) {
mChoiceList = choiceList;
}
public String getChoices() {
return mChoices;
}
public void setChoices(String choices) {
mChoices = choices;
}
public void setAnswerIndex(int mAnswerIndex) {
this.mAnswerIndex = mAnswerIndex;
}
public int getAnswerIndex() {
return mAnswerIndex;
}
public String getCategory() {
return mCategory;
}
public void setCategory(String categorie) {
mCategory = categorie;
}
public String getTrueAnswer() {
return mTrueAnswer;
}
public void setTrueAnswer(String trueAnswer) {
mTrueAnswer = trueAnswer;
}
public String getDifficulty() {
return mDifficulty;
}
public void setDifficulty(String difficulty) {
mDifficulty = difficulty;
}
}
QuestionBank (this is like a list of Questions) :
package com.jojo.jojozquizz.model;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class QuestionBank {
private List<Question> mQuestionList;
public int mNextQuestionIndex;
public QuestionBank() {
mQuestionList = new LinkedList<>();
mNextQuestionIndex = 0;
}
public QuestionBank(List<Question> questionList, boolean shuffle) {
mQuestionList = questionList;
if (shuffle)
Collections.shuffle(mQuestionList);
mNextQuestionIndex = 0;
}
public Question getQuestion() {
if (mNextQuestionIndex == mQuestionList.size())
mNextQuestionIndex = 0;
return mQuestionList.get(mNextQuestionIndex++);
}
public Question getQuestion(int i) {
return mQuestionList.get(i);
}
public void reShuffle() {
Collections.shuffle(mQuestionList);
}
public void addQuestion(Question question) {
mQuestionList.add(question);
}
public int returnListSize() {
return mQuestionList.size();
}
}
And APIListener :
package com.jojo.jojozquizz.tools;
import com.jojo.jojozquizz.model.Question;
public interface APIListener {
void questionReceived(Question q);
}
API calling is an asynchronous process. So getQuestionFromApi(url); might took some time, so if you try text.setText(mQuestionBank.getQuestion(0).getQuestion()); after getQuestionFromApi(url); line, it won't work. You could use LiveData to handle this case. Like:
class QuestionBank {
MutableLiveData<List<Question>> mQuestionList;
public int mNextQuestionIndex;
public QuestionBank() {
mQuestionList = new MutableLiveData<>(new LinkedList<>());
mNextQuestionIndex = 0;
}
public QuestionBank(List<Question> questionList, boolean shuffle) {
mQuestionList.setValue(questionList);
if (shuffle)
Collections.shuffle(mQuestionList.getValue());
mNextQuestionIndex = 0;
}
public Question getQuestion() {
if (mNextQuestionIndex == mQuestionList.getValue().size())
mNextQuestionIndex = 0;
return mQuestionList.getValue().get(mNextQuestionIndex++);
}
public Question getQuestion(int i) {
return mQuestionList.getValue().get(i);
}
public void reShuffle() {
Collections.shuffle(mQuestionList.getValue());
}
public void addQuestion(Question question) {
List<Question> tempQ = mQuestionList.getValue();
tempQ.add(question);
mQuestionList.setValue(tempQ);
}
public int returnListSize() {
return mQuestionList.getValue().size();
}
}
And inside onCreate() observe if any data has been added or not and then setText() to TextView. Like:
QuestionBank questionBank = new QuestionBank();
questionBank.mQuestionList.observe(getViewLifecycleOwner(), new Observer<List<Question>>() {
#Override
public void onChanged(List<Question> questions) {
if (!questions.isEmpty()){
textView.setText(questions.get(0).getQuestion());
Log.d("TAG==>>","New Question added Total size = "+questions.size());
}
}
});
This is my MainActivity.java :
package example.com.getdata;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public static final String JSON_URL = "http://172.31.131.52:8081/application/status";
private Button buttonGet;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonGet = (Button) findViewById(R.id.button2);
}
private void sendRequest(){
StringRequest stringRequest = new StringRequest(JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.getMessage(),Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showJSON(String json) {
Product product = new Product(json);
ArrayList<JSONObject> listItems= product.parseJSON();
listView = (ListView) findViewById(R.id.list_view);
CustomList customerList = new CustomList(this,R.layout.list_view_layout,R.id.textViewName, listItems);
//customerList.notifyDataSetChanged();
listView.setAdapter(customerList);
}
public void clickHere(View v) {
sendRequest();
}
}
Product.java
package example.com.getdata;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import static com.android.volley.VolleyLog.TAG;
public class Product {
public String productName;
public String description;
public int priceInDollars;
//public int productID;
public static final String KEY_Name = "productName";
public static final String KEY_Desc = "description";
//public static final String KEY_ID= "ProductID";
public static final String KEY_Price ="priceInDollars" ;
private JSONArray users = null;
private String json;
public Product(String json){
this.json =json;
}
protected ArrayList<JSONObject> parseJSON(){
JSONArray jsonArray=null;
ArrayList<JSONObject> aList=new ArrayList<JSONObject>();
try {
jsonArray = new JSONArray(json);
Log.d("Debugging...", jsonArray.toString());
if(jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
productName = jo.getString(KEY_Name);
description = jo.getString(KEY_Desc);
priceInDollars = jo.getInt(KEY_Price);
aList.add(jsonArray.getJSONObject(i));
// productID = jo.getInt(KEY_ID);
}
return aList;
}
else {
Log.d(TAG, "parseJSON: Null condition");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
CustomList.java
package example.com.getdata;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class CustomList extends ArrayAdapter<String> {
private ArrayList<JSONObject> list;
private int vg;
private Activity context;
public CustomList(Activity context,int vg, int id, ArrayList<JSONObject> list ) {
super(context,R.layout.list_view_layout, id);
this.vg = vg;
this.context = context;
this.list=list;
// this.productID=productID;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View listViewItem = inflater.inflate(vg, parent, false);
TextView textViewName = (TextView) listViewItem.findViewById(R.id.textViewName);
TextView textViewDescription = (TextView) listViewItem.findViewById(R.id.textViewDescription);
TextView textViewPrice = (TextView) listViewItem.findViewById(R.id.textViewPrice);
// TextView textViewID = (TextView) listViewItem.findViewById(R.id.textViewID);
try {
textViewName.setText(list.get(position).getString("productName"));
textViewDescription.setText(list.get(position).getString("description"));
textViewPrice.setText(list.get(position).getString("priceInDollars"));
}
catch (JSONException e) {
e.printStackTrace();
}
// textViewID.setText(productID);
return listViewItem;
}
}
I have tried and searched for answers online and I am still not able to figure out the problem. I am unable to see the list of objects. Through debugging, I am sure that the objects are read into the json objects, still I am not able to display the objects in a listView.
Any help is appreciated.
You need to crate constructor with all variables of Product class and put all values in Product class object and add into ArrayList .
See Product Class :
public class Product {
public String productName;
public String description;
public int priceInDollars;
//public int productID;
public static final String KEY_Name = "productName";
public static final String KEY_Desc = "description";
//public static final String KEY_ID= "ProductID";
public static final String KEY_Price ="priceInDollars" ;
private JSONArray users = null;
private String json;
public Product(String productName, String json, JSONArray users, int priceInDollars, String description) {
this.productName = productName;
this.json = json;
this.users = users;
this.priceInDollars = priceInDollars;
this.description = description;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static String getKEY_Name() {
return KEY_Name;
}
public static String getKEY_Price() {
return KEY_Price;
}
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
public JSONArray getUsers() {
return users;
}
public void setUsers(JSONArray users) {
this.users = users;
}
public static String getKEY_Desc() {
return KEY_Desc;
}
public int getPriceInDollars() {
return priceInDollars;
}
public void setPriceInDollars(int priceInDollars) {
this.priceInDollars = priceInDollars;
}
}
And When your are parsing your data you need to change like below code:
protected ArrayList<Product> parseJSON(){
JSONArray jsonArray=null;
ArrayList<Product> aList=new ArrayList<Product>();
try {
jsonArray = new JSONArray(json);
Log.d("Debugging...", jsonArray.toString());
if(jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
String productName = jo.optString(KEY_Name);
String description = jo.optString(KEY_Desc);
String priceInDollars = jo.optInt(KEY_Price);
Product product = new Product(productName,json,
jsonArray.getJSONObject(i),priceInDollars,description);
aList.add(product);
// productID = jo.getInt(KEY_ID);
}
return aList;
}
else {
Log.d(TAG, "parseJSON: Null condition");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
Also you need to change in Adapter class where you have passes ArrayList<JsonArray> in this case you have to pass ArrayList<Product>.
You missed
#override
public int getCount()
{
return list.size();
}
and make sure you either "setAdapter" on your listview after getting the json or call "notifydatasetchanged" method
Use
super(context,R.layout.list_view_layout, list);
instead of
super(context,R.layout.list_view_layout, id);
Make sure getCount() is properly implemented in Adapterclass:
#Override
public int getCount(){
return list.size();
}
Extend the CustomList class as:
type JSONObject
instead of
type String
I want to send a Listview Data to another Activity.
check my code:
ActorAdapater.java
package anyname;
import java.io.InputStream;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ActorAdapter extends ArrayAdapter<Actors> {
ArrayList<Actors> actorList;
LayoutInflater vi;
int Resource;
ViewHolder holder;
public ActorAdapter(Context context, int resource, ArrayList<Actors> objects) {
super(context, resource, objects);
vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resource = resource;
actorList = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// convert view = design
View v = convertView;
if (v == null) {
holder = new ViewHolder();
v = vi.inflate(Resource, null);
holder.imageview = (ImageView) v.findViewById(R.id.ivImage);
holder.tvName = (TextView) v.findViewById(R.id.tvName);
holder.tvDescription = (TextView) v.findViewById(R.id.tvDescriptionn);
holder.tvDOB = (TextView) v.findViewById(R.id.tvDateOfBirth);
holder.tvCountry = (TextView) v.findViewById(R.id.tvCountry);
holder.tvHeight = (TextView) v.findViewById(R.id.tvHeight);
holder.tvSpouse = (TextView) v.findViewById(R.id.tvSpouse);
holder.tvChildren = (TextView) v.findViewById(R.id.tvChildren);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.imageview.setImageResource(R.drawable.ic_launcher);
new DownloadImageTask(holder.imageview).execute(actorList.get(position).getImage());
holder.tvName.setText(actorList.get(position).getName());
holder.tvDescription.setText(actorList.get(position).getDescription());
holder.tvDOB.setText("B'day: " + actorList.get(position).getDob());
holder.tvCountry.setText(actorList.get(position).getCountry());
holder.tvHeight.setText("Height: " + actorList.get(position).getHeight());
holder.tvSpouse.setText("Spouse: " + actorList.get(position).getSpouse());
holder.tvChildren.setText("Children: " + actorList.get(position).getChildren());
return v;
}
static class ViewHolder {
public ImageView imageview;
public TextView tvName;
public TextView tvDescription;
public TextView tvDOB;
public TextView tvCountry;
public TextView tvHeight;
public TextView tvSpouse;
public TextView tvChildren;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Actors.java
public class Actors {
private String name;
private String description;
private String dob;
private String country;
private String height;
private String spouse;
private String children;
private String image;
public Actors() {
// TODO Auto-generated constructor stub
}
public Actors(String name, String description, String dob, String country,
String height, String spouse, String children, String image) {
super();
this.name = name;
this.description = description;
this.dob = dob;
this.country = country;
this.height = height;
this.spouse = spouse;
this.children = children;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getSpouse() {
return spouse;
}
public void setSpouse(String spouse) {
this.spouse = spouse;
}
public String getChildren() {
return children;
}
public void setChildren(String children) {
this.children = children;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
MainActivity.java
package ANYNAME;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class MainActivity extends Activity {
ArrayList<Actors> actorsList;
ActorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actorsList = new ArrayList<Actors>();
new JSONAsyncTask().execute("json link here.xml");
ListView listview = (ListView)findViewById(R.id.list);
adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), actorsList.get(position).getName(), Toast.LENGTH_LONG).show();
}
});
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("Loading, please wait");
dialog.setTitle("Connecting server");
dialog.show();
dialog.setCancelable(false);
}
#Override
protected Boolean doInBackground(String... urls) {
try {
//------------------>>
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("actors");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Actors actor = new Actors();
actor.setName(object.getString("name"));
actor.setDescription(object.getString("description"));
actor.setDob(object.getString("dob"));
actor.setCountry(object.getString("country"));
actor.setHeight(object.getString("height"));
actor.setSpouse(object.getString("spouse"));
actor.setChildren(object.getString("children"));
actor.setImage(object.getString("image"));
actorsList.add(actor);
}
return true;
}
//------------------>>
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
if(result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
When users Click on Listview Content & Pass Listview Data to NewActivity.java
You can use Intent to pass data from one Activity to another.
Intent intent=new Intent(MainActivity.this,NewActivity.class);
intent.putExtra("key",value);//
......
startActivity(intent);
In your NewActivity access value as:
variable=getIntent().getXXX("key");
Try to use GSON library to generate json (String) from your model. Put it to the Intent and start new Activity.
you can use shared SharedPrefences
SharedPreferences pref = getSharedPreferences("MYPrefrences", 0);
For save
Editor prefsEditor = pref.edit();
Gson gson = new Gson();
String json = gson.toJson("MyObject");
prefsEditor.putString("MyObject", json);
prefsEditor.commit();
For get
Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
Actor actor = gson.fromJson(json, Actor.class);
Implement Serializable (http://developer.android.com/reference/java/io/Serializable.html) in your Actors.java class. In your setOnItemClickListener, use the following code:
Intent newIntent = new Intent(thisActivity.this, NextActivity.class);
newIntent.putExtra("key", value);
startActivity(newIntent);
In your NextActivity.class, you can get back the object like this:
Intent intent = getIntent();
YourClass object = intent.getSerializableExtra("key");
This will give you the whole object, with all its properties.
Replace your code with this,
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long id) {
Actors myActor = actorsList.get(position);
// create JSON object from the above object with getter methods
JSONObject myActorJSON = new JSONObject();
myActorJSON.put("name", myActor.getName());
myActorJSON.put("description", myActor.getDescription());
myActorJSON.put("dob", myActor.getDOB());
myActorJSON.put("country", myActor.getCountry());
myActorJSON.put("height", myActor.getHeight());
myActorJSON.put("spouse", myActor.getSpouse());
myActorJSON.put("children", myActor.getChildren());
myActorJSON.put("image", myActor.getImage());
//you can send the Actors object or JSONObject to the new Activity
// through intent as
Intent i = new Intent(this, NewActivity.class);
i.putExtra("ACTOR_OBJECT", myActor); //Actors class should extend serializable interface
i.putExtra("ACTOR_JSON_OBJECT", myActorJSON.toString());
startActivity(i);
}
and
//Now in NewActivity.class extract tha data from intent as
Intent i = getIntent();
Actors receivedActorObject = (Actors)i.getSerializableExtra("ACTOR_OBJECT");
String JSONString = i.getStringExtra("ACTOR_JSON_OBJECT");
try {
JSONObject receivedActorJSON = new JSONObject(JSONString);
} catch (JSONException e) {
e.printStackTrace();
}
Let me know if it works for you...
And do mark it as an answer so that it would be useful to others...
On your onClick method
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), actorsList.get(position).getName(), Toast.LENGTH_LONG).show();
Actor selectedActor = actorsList.get(position);
JSONObject obj = new JsonObject();
obj.put("name",selectedActor.getName());
//add other values of actor like that
Intent i = new Intent(MainActirity.this,otherActivity.class);
i.putExtra("Actor",obj.toString());
startActivity(i);
}
In your receiving activity
Intent i = getIntent();
JSONObject obj = new JSONObject(i.getStringExtra("Actor"));
Also have a look at Intent