Hi guys I dont have much experience with AsyncTask and this is my first time using RecyclerView besides a couple of tutorials I done to learn about it.
If I use dummy data in EventActivity everything works fine and a list shown on the screen. But when I create an ArrayList of EventItems and pass that to the adapter it's just a blank screen. The JSON from localhost is being parsed and sent to the EventItem class. I have tried several things to get it to work but as my experience with AsyncTask and RecyclerView are limited I end up just crashing the app and getting a null pointer exception.
I think that the RecyclerView is being created before the JSON has been retrieved from localhost and this is what's causing the blank screen or null pointer exception but I'm not 100% sure and dont know how to fix the issue if I am correct.
Any help is appreciated.
EventActivity
public class EventActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event);
fetchEvents();//call EventBackgroundWorker
//ArrayList<EventItem> eventList = new EventItem().getRecyclerList();//causes java null pointer exception
ArrayList<EventItem> eventList = new ArrayList<>();
//Dummie data
// eventList.add(new EventItem (1, "Title1", "Date", "endDate", "Location1", 5, 1111));
// eventList.add(new EventItem (R.drawable.ic_favourite, "Title2", "11/07/2018", "11/07/2018", "Wales", 10, 5));
// eventList.add(new EventItem (R.drawable.ramspeed_custom, "Title3", "11/01/2018", "11/09/2018", "Paris, France", 0, 90));
// eventList.add(new EventItem (R.drawable.ramspeed_custom, "Title4", "12/01/2018", "11/09/2018", "New York", 20, 500));
// eventList.add(new EventItem (R.drawable.ic_favourite, "Title5", "Mon 11/05/2015", "11/09/2018", "London, England", 5, 500));
// eventList.add(new EventItem (R.drawable.biker, "Title6", "Mon 11/05/2018", "20/07/2018", "Swords Dublin", 0, 500));
mRecyclerView = (RecyclerView) findViewById(R.id.event_recycler_view);
mRecyclerView.setHasFixedSize(true);//increase performance of app if recyclerView does not increase in size
mLayoutManager = new LinearLayoutManager(this);
// mAdapter = new EventAdapter(eventList);
mAdapter = new EventAdapter(eventList);//context added for testing //////////////////////////////
// mAdapter = new EventAdapter(new ArrayList<EventItem>(0));
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
// buildRecyclerView();
}
//run background thread
private void fetchEvents(){
// String username = "user";
// String userPassword = "password";
String startConnectionCondition = "event";
//this passes the context
EventBackgroundWorker backgroundWorker = new EventBackgroundWorker(this);
backgroundWorker.execute(startConnectionCondition, null);
}
/* private void buildRecyclerView(){
ArrayList<EventItem> eventList = new EventItem().getRecyclerList();
mRecyclerView = (RecyclerView) findViewById(R.id.event_recycler_view);
mRecyclerView.setHasFixedSize(true);//increase performance of app if recyclerView does not increase in size
mLayoutManager = new LinearLayoutManager(this);
// mAdapter = new EventAdapter(eventList);
mAdapter = new EventAdapter(eventList);//context added for testing
// mAdapter = new EventAdapter(new ArrayList<EventItem>(0));
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
*/
/* public void showEventList(boolean b){
ArrayList<EventItem> eventList = new ArrayList<>();
for(int i =0; i< eventList.size(); i++){
eventList.get(i);
Log.d("tag","eventList from main " + eventList);
}
mAdapter = new EventAdapter(eventList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}*/
}//MainActivity
EventAdapter
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
private ArrayList<EventItem> mEventList;
Context context;
//constructor for EventAdapter
public EventAdapter(ArrayList<EventItem> eventList){
// context =c;
mEventList = eventList;
Log.d("tag","EventAdapter eventlist variable called from constructor " + eventList);
}
public static class EventViewHolder extends RecyclerView.ViewHolder{
public ImageView mPromoImage;
public TextView mTitle;
public TextView mStartDate;
public TextView mEndDate;
public TextView mLocation;
public TextView mFee;
public ImageView mFavourite;
//constructor for EventViewHolder class
public EventViewHolder(View itemView) {
super(itemView);
// mPromoImage = (ImageView) itemView.findViewById(R.id.event_promotional_image);
mTitle = (TextView) itemView.findViewById(R.id.event_title_textView);
mStartDate = (TextView) itemView.findViewById(R.id.event_start_textView);
mEndDate = (TextView) itemView.findViewById(R.id.event_end_textView);
mLocation = (TextView) itemView.findViewById(R.id.event_location_textView);
mFee = (TextView) itemView.findViewById(R.id.event_fee_textView);
// mFavourite = (ImageView) itemView.findViewById(R.id.event_favourite_image);
Log.d("tag", "EventViewHolder being called");
}
}//EventViewHolder class
#Override
public EventViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_event, parent, false);
//create view holder
EventViewHolder viewHolder = new EventViewHolder(v);
return viewHolder;
}
//pass values to inflated XML Views in item_event.xml
#Override
public void onBindViewHolder(EventViewHolder holder, int position) {
EventItem currentEvent = mEventList.get(position);
// holder.mPromoImage.setImageResource(currentEvent.getEventPromoImage());
holder.mTitle.setText(currentEvent.getEventTitle());
holder.mStartDate.setText(currentEvent.getEventStartDate());
holder.mEndDate.setText(currentEvent.getEventEndDate());
holder.mLocation.setText(currentEvent.getEventLocation());
holder.mFee.setText(String.valueOf(currentEvent.getEventFee()));//int value passed
// holder.mFavourite.setImageResource(currentEvent.getEventFavourite());
//Log.d("tag", "position" + position );
Log.d("tag","eventAdapter " + currentEvent.getEventTitle());
}
//how many items there will be
#Override
public int getItemCount() {
return mEventList.size();
}
}
EventItem
public class EventItem {
private int mEventPromoImage;
private int mId;
private String mEventTitle;
private String mEventStartDate;
private String mEventEndDate;
private String mEventLocation;
private int mEventFee;
private int mEventViews;
// public EventItem(){}
public EventItem(int id, String eventTitle, String eventStartDate,
String eventEndDate, String eventLocation, int eventFee, int eventViews){
// mEventPromoImage = eventPromoImage;
mId = id;
mEventTitle = eventTitle;
mEventStartDate = eventStartDate;
mEventEndDate = eventEndDate;
mEventLocation = eventLocation;
mEventFee = eventFee;
mEventViews = eventViews;
Log.d("tag","EVENTITEM title EventItem" + mEventTitle);
// Log.d("tag","EVENTITEM startDate EventItem" + mEventStartDate );
// Log.d("tag","EVENTITEM endDate EventItem" + mEventEndDate );
// Log.d("tag","EVENTITEM address EventItem" + mEventLocation);
// Log.d("tag","EVENTITEM fee EventItem" + mEventFee);
}
public int getEventPromoImage() {
return mEventPromoImage;
}
public void setEventPromoImage(int mEventPromoImage) {
this.mEventPromoImage = mEventPromoImage;
}
public int getEventId() {
return mId;
}
public void setEventId(int mId){
this.mId = mId;
}
public String getEventTitle() {
Log.d("tag","getEventTitle() " + mEventTitle);
return mEventTitle;
}
public void setEventTitle(String mEventTitle) {
this.mEventTitle = mEventTitle;
}
public String getEventStartDate() {
return mEventStartDate;
}
public void setEventStartDate(String mEventStartDate) {
this.mEventStartDate = mEventStartDate;
}
public String getEventEndDate(){
return mEventEndDate;
}
public void setEventEndDate(String mEventEndDate){
this.mEventEndDate = mEventEndDate;
}
public String getEventLocation() {
return mEventLocation;
}
public void setEventLocation(String mEventLocation) {
this.mEventLocation = mEventLocation;
}
public int getEventFee() {
return mEventFee;
}
public void setEventFee(int mEventFee) {
this.mEventFee = mEventFee;
}
public int getEventViews(){
return mEventViews;
}
public void getEventViews(int mEventViews) {
this.mEventViews = mEventViews;
}
public ArrayList<EventItem> getRecyclerList(){
ArrayList event = new ArrayList();
event.add(mEventTitle);
event.add(mEventStartDate);
event.add(mEventEndDate);
event.add(mEventLocation);
event.add(mEventFee);
event.add(mEventViews);
return event;
}
}
EventBackgroundWorker
public class EventBackgroundWorker extends AsyncTask<String, Void, String> {
Context context;
AlertDialog alert;
public static final String REQUEST_URL = "http://10.0.2.2/m/event/";
public EventBackgroundWorker(Context ctxt) {
context = ctxt;
}
//Invoked on UI thread before doInBackground is called
#Override
protected void onPreExecute() {
alert = new AlertDialog.Builder(context).create();
alert.setTitle("Result from server");
}
#Override
protected String doInBackground(String... params) {
String type = params[0];//eventList
//String login_url = "http://10.0.2.2/m/event/";
if(type.equals("event")){
try {
String user_name = params[1];
URL url = new URL(REQUEST_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.connect();//works without this connect Find out why
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("getEvents", "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
//read response
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line;
while((line = bufferedReader.readLine()) != null){
result += line;
}
//parse JSON event Array
// Create an empty ArrayList that we can start adding events to
ArrayList<EventItem> eventArray = new ArrayList<>();
JSONArray baseJsonResponse = new JSONArray(result);
for(int i =0; i < baseJsonResponse.length(); i++){
JSONObject event = baseJsonResponse.getJSONObject(i);
int id = event.getInt("id");
String title = event.getString("title");
String address = event.getString("address");
String startDate = event.getString("startDate");
String endDate = event.getString("endDate");
int fee = event.getInt("fee");
int views = event.getInt("views");
//Send data to eventItem Object
EventItem eventObject = new EventItem(id,title,address,startDate,endDate,fee,views);
eventArray.add(eventObject);
/* Log.d("tag", "JSON id " + id);
Log.d("tag", "JSON title " + title);
Log.d("tag", "JSON address " + address);
Log.d("tag", "JSON startDate " + startDate);
Log.d("tag", "JSON endDate " + endDate);
Log.d("tag", "JSON fee " + fee);
Log.d("tag", "JSON views " + views);*/
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (MalformedURLException e) {//added for URL object
e.printStackTrace();
} catch (IOException e) {
//HTPURLConnection
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
//results from doInBackground are passed here
#Override
protected void onPostExecute(String result) {
Log.d("tag", "onPostExecute called" + result);
alert.setMessage(result);
alert.show();
}
}
The AsyncTask creates eventArray but does nothing with it. doInBackground() should return the eventArray and onPostExecute() should set it as adapter content (by a Callback or by setting the Adapter instance at the AsyncTask object). Your Adapter should have a setter for the content which should call notifyDataSetChanged().
Related
I am trying to display posts from a server in listView. So I used recycle-view to achieve that. Everything is working fine except that ll items are displaying twice.
I counted the total fetched items from server, and the count is 5, but adapter.getItemCount is showing 10.
After searching hours on the internet, I tried following :
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
and
homeFragmentAdapter.setHasStableIds(true);
Below is my fragment...
package com.example.projectName;
import static android.content.Context.MODE_PRIVATE;
import static android.webkit.ConsoleMessage.MessageLevel.LOG;
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
public class HomeFollowersFragment extends Fragment implements InfiniteScrollListener.OnLoadMoreListener, RecyclerViewItemListener {
private static final String TAG = "HomeFollowersFragment";
private static final String URL = "https://api.androidhive.info/json/movies_2017.json";
private RecyclerView recyclerView;
private ProgressBar postLoader;
FFmpeg ffmpeg;
// private List<Movie> movieList;
// private HomeAdapter mAdapter;
private List<PostList> postListGlobal = new ArrayList<>();
List<VerticalDataModal> verticalDataModals;
List<HorizontalDataModal> horizontalDataModals;
private SwipeRefreshLayout swipeMore;
private InfiniteScrollListener infiniteScrollListener;
private HomeFragmentAdapter homeFragmentAdapter;
SharedPreferences sharedPreferences;
private Boolean isLoggedIn = false;
private String email = "";
private String token = "";
private String userId = "";
private Dialog customLoader;
SkeletonScreen skeletonScreen;
private int pastVisiblesItems, visibleItemCount, totalItemCount;
private boolean loading = false;
private EndlessScrollListener scrollListener;
SharedPreferences sp;
SharedPreferences.Editor Ed;
public HomeFollowersFragment() {
//super();
}
/**
* #return A new instance of fragment HomeFollowersFragment.
*/
public static HomeFollowersFragment newInstance() {
return new HomeFollowersFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
// ((AppCompatActivity) getActivity()).getSupportActionBar().show();
try{
sharedPreferences = getActivity().getSharedPreferences("Login", MODE_PRIVATE);
email = sharedPreferences.getString("email", null);
token = sharedPreferences.getString("token", null);
isLoggedIn = sharedPreferences.getBoolean("isLoggedIn", false);
userId = sharedPreferences.getString("id", null);
}catch (Exception e){
e.printStackTrace();
Log.d("StackError", "StackError: "+e);
}
sp = getActivity().getSharedPreferences("Posts", MODE_PRIVATE);
if(!isLoggedIn || token == null || userId == null){
Intent intent = new Intent(getActivity(), RegisterActivity.class);
intent.putExtra("loginFrom", "profile");
startActivity(intent);
}
recyclerView = view.findViewById(R.id.recycler_view);
postLoader = view.findViewById(R.id.post_loader);
swipeMore = view.findViewById(R.id.swipe_layout);
homeFragmentAdapter = new HomeFragmentAdapter(postListGlobal, this, "home");
if(sp.contains("postListGlobal"))
skeletonScreen = Skeleton.bind(recyclerView)
.adapter(homeFragmentAdapter)
.shimmer(true)
.angle(20)
.frozen(false)
.duration(1200)
.count(10)
.load(R.layout.item_skelton_home_page)
.show(); //default count is 10
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
StaggeredGridLayoutManager sLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(sLayoutManager);
homeFragmentAdapter.setHasStableIds(true);
recyclerView.setAdapter(homeFragmentAdapter);
recyclerView.setNestedScrollingEnabled(false);
customLoader = new Dialog(getActivity(), R.style.crystal_range_seek_bar);
customLoader.setCancelable(false);
View loaderView = getLayoutInflater().inflate(R.layout.custom_loading_layout, null);
customLoader.getWindow().getAttributes().windowAnimations = R.style.crystal_range_seek_bar;
customLoader.getWindow().setBackgroundDrawableResource(R.color.translucent_black);
ImageView imageLoader = loaderView.findViewById(R.id.logo_loader);
Glide.with(this).load(R.drawable.logo_loader).into(imageLoader);
customLoader.setContentView(loaderView);
if(homeFragmentAdapter.getItemCount() == 0 && !loading){
// server fetchdata
Log.d(TAG, "no item available..");
postLoader.setVisibility(View.VISIBLE);
loading = true;
fetchStoreItems();
}else{
postLoader.setVisibility(View.GONE);
}
swipeMore.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.d(TAG, "on refresh...");
fetchStoreItems();
}
});
return view;
}
#Override
public void onItemClicked(int position) {
Log.d(TAG, "click position: "+position);
Toast.makeText(getActivity(),postListGlobal.get(position).getTitle(),Toast.LENGTH_SHORT).show();
// Toast.makeText(getActivity(),""+position, Toast.LENGTH_SHORT).show();
}
public int getLastVisibleItem(int[] lastVisibleItemPositions) {
int maxSize = 0;
for (int i = 0; i < lastVisibleItemPositions.length; i++) {
if (i == 0) {
maxSize = lastVisibleItemPositions[i];
}
else if (lastVisibleItemPositions[i] > maxSize) {
maxSize = lastVisibleItemPositions[i];
}
}
return maxSize;
}
#Override
public void onLoadMore() {
homeFragmentAdapter.addNullData();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
homeFragmentAdapter.removeNull();
Toast.makeText(getContext(), "load more here...", Toast.LENGTH_LONG).show();
// fetchStoreItems();
swipeMore.setRefreshing(false);
}
}, 2000);
}
private void fetchStoreItems() {
RequestQueue queue = Volley.newRequestQueue(getActivity());
Log.d(TAG, "Post Data Followers: "+Constant.FETCH_POSTS_API);
CacheRequest cacheRequest = new CacheRequest(0, Constant.FETCH_POSTS_API, new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
try {
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
if (response == null) {
Toast.makeText(getActivity(), "Couldn't fetch the store items! Pleas try again.", Toast.LENGTH_LONG).show();
loading = false;
return;
}
JSONObject postObj = new JSONObject(jsonString);
System.out.println("post full data... : " + postObj);
if (postObj.getBoolean("Status")) {
try {
postLoader.setVisibility(View.GONE);
JSONArray arrayResponse = postObj.optJSONArray("Data");
int dataArrLength = arrayResponse.length();
if(dataArrLength == 0){
Toast.makeText(getActivity(), "No posts available at this time, you can create yout own post by clicking on mic button", Toast.LENGTH_SHORT).show();
}
postListGlobal.clear();
Log.d(TAG, "Total Posts count: "+dataArrLength);
for(int i=0; i<dataArrLength; i++) {
try {
JSONObject dataListObj = arrayResponse.optJSONObject(i);
System.out.println("post full data... : " + dataListObj);
JSONObject postDetailObj = dataListObj.optJSONObject("post_detail");
JSONObject followDtatusObj = dataListObj.optJSONObject("follow_status");
JSONArray postFilesArr = dataListObj.optJSONArray("post_files");
JSONObject userDatasObj = postDetailObj.optJSONObject("user");
String userId = userDatasObj.optString("id");
String userName = userDatasObj.optString("email");
String userImage = userDatasObj.optString("email");
boolean followStatus = followDtatusObj.optBoolean("follow");
String postId = postDetailObj.optString("id");
String postTitle = postDetailObj.optString("post_title");
String postDescription = postDetailObj.optString("post_description");
String postCoverUrl = postDetailObj.optString("post_coverurl", "1");
String postViewType = postDetailObj.optString("view_type", "1");
String postAllowComment = postDetailObj.optString("allow_comments", "1");
String postAllowDownload = postDetailObj.optString("allow_download", "1");
String postTotalPost = postDetailObj.optString("total_post", "1");
String postPostSection = postDetailObj.optString("post_section", "image");
String postActiveStatus = postDetailObj.optString("is_active", "1");
String postTotalViews = postDetailObj.optString("total_watched","0");
String postTotalShare = postDetailObj.optString("total_share","0");
String postTotalDownload = postDetailObj.optString("total_download","0");
String postTotalReaction = postDetailObj.optString("total_reaction","0");
String postTotalLike = postDetailObj.optString("total_like","0");
String postTotalSmile = postDetailObj.optString("smile_reaction","0");
String postTotalLaugh = postDetailObj.optString("laugh_reaction","0");
String postTotalSad = postDetailObj.optString("sad_reaction","0");
String postTotalLove = postDetailObj.optString("love_reaction","0");
String postTotalShock = postDetailObj.optString("shock_reaction","0");
int totalPostFiles = Integer.parseInt(postTotalPost);
int postArrLength = postFilesArr.length();
String postImageUrl = null;
String postMusicUrl = null;
String commonUrl = "http://serverName.com/";
if(postArrLength >= 1){
JSONObject dataFilesListObj = postFilesArr.optJSONObject(0);
// System.out.println("post files full data... : " + dataFilesListObj);
String postFileId = dataFilesListObj.optString("id");
postImageUrl = dataFilesListObj.optString("image_file_path");
postMusicUrl = dataFilesListObj.optString("music_file_path");
System.out.println("post files full data... : " + dataFilesListObj);
}
System.out.println("post files full data... : " + commonUrl+postMusicUrl);
System.out.println("post files full data... : " + commonUrl+postImageUrl);
PostList postList = new PostList();
postList.setId(postId);
postList.setTitle(postTitle);
postList.setTotalPost(""+dataArrLength);
postList.setTotalView(postTotalViews);
postList.setTotalReaction(postTotalReaction);
postList.setMusicPath(commonUrl+postMusicUrl);
postList.setImagePath(commonUrl+postImageUrl);
if(postImageUrl == null){
postList.setImagePath("https://amazonBucket.s3.location.amazonaws.com/images/pic1.jpg");
}
postList.setUserId(userId);
postList.setUserName(userName);
postList.setPostDataObject(arrayResponse);
postListGlobal.add(postList);
Log.d(TAG, "Total Posts: "+dataListObj);
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Post Data Error1: "+e);
Toast.makeText(getActivity(), "File now found", Toast.LENGTH_LONG).show();
loading = false;
}
}
} catch (Exception e){
e.printStackTrace();
Log.d(TAG, "Post Data Error2: "+e);
Toast.makeText(getActivity(), R.string.server_error, Toast.LENGTH_LONG).show();
loading = false;
}
}else{
try {
Toast.makeText(getActivity(), new JSONObject(jsonString).getString("Message"), Toast.LENGTH_LONG).show();
} catch (JSONException ex) {
ex.printStackTrace();
Log.d(TAG, "Post Data Error3: "+ex);
Toast.makeText(getActivity(), R.string.server_error, Toast.LENGTH_SHORT).show();
}
loading = false;
}
// refreshing recycler view
homeFragmentAdapter.removeNull();
homeFragmentAdapter.addData(postListGlobal);
homeFragmentAdapter.notifyDataSetChanged();
// save in local memory
// saveArrayList(postListGlobal, "postListGlobal");
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Post Data Error4: "+e);
}
loading = true;
homeFragmentAdapter.notifyDataSetChanged();
swipeMore.setRefreshing(false);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "onErrorResponse: "+ error, Toast.LENGTH_SHORT).show();
swipeMore.setRefreshing(false);
loading = true;
homeFragmentAdapter.notifyDataSetChanged();
postLoader.setVisibility(View.VISIBLE);
loading = false;
Log.d(TAG, "Post Data Error5: "+error);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
String finalToken = "Bearer "+token;
params.put("Authorization", finalToken);
params.put("Content-Type", "application/json");
return params;
}
};
// Add the request to the RequestQueue.
queue.add(cacheRequest);
}
private class CacheRequest extends Request<NetworkResponse> {
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public CacheRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
#Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
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;
return Response.success(response, cacheEntry);
}
#Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
Log.d(TAG, "Post Data volleyError: "+volleyError);
return super.parseNetworkError(volleyError);
}
#Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
}
and Adapter Class
package com.example.ProjectName;
public class HomeFragmentAdapter extends RecyclerView.Adapter <HomeFragmentAdapter.HomeViewHolder>{
// private ArrayList<Integer> dataList;
private List<PostList> postListGlobal;
int VIEW_TYPE_LOADING;
int VIEW_TYPE_ITEM;
Context context;
private RecyclerViewItemListener callback;
FFmpeg ffmpeg;
String callingPage;
public HomeFragmentAdapter(List<PostList> postListGlobal, RecyclerViewItemListener callback, String callingPage) {
this.postListGlobal = postListGlobal;
this.callback = callback;
this.callingPage = callingPage;
// setHasStableIds(true);
}
#NonNull
#Override
public HomeFragmentAdapter.HomeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View root = null;
context = parent.getContext();
root = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_home_tile_list, parent, false);
return new DataViewHolder(root);
}
#Override
public void onBindViewHolder(#NonNull HomeFragmentAdapter.HomeViewHolder holder, int position) {
if (holder instanceof DataViewHolder) {
final PostList postList = postListGlobal.get(position);
holder.postTitle.setText(postList.getTitle());
holder.postWatch.setText(postList.getTotalView());
holder.postReaction.setText(postList.getTotalReaction());
String imageUrl = postList.getImagePath();
// String imageUrl = Constant.SERVER_URL+"/"+postList.getImagePath();
String musicUrl = postList.getMusicPath();
// String musicUrl = Constant.SERVER_URL+"/"+postList.getMusicPath();
Log.d(TAG, "Post url: "+imageUrl+" -- "+musicUrl);
// int totalMusicTime = getDurationVal(musicUrl, "second");
holder.postTime.setText(postList.getTotalPost());
holder.thumbnail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
callback.onItemClicked(position);
Log.d("homeView", "screenName : "+callingPage);
if(callingPage.equals("home")){
Log.d("homeView", "screenName : "+position);
Intent intent = new Intent(context, MainViewActivity.class);
intent.putExtra("loginFrom", "homeView");
intent.putExtra("postDataObj", postList.getPostDataObject().toString());
intent.putExtra("postPosition", ""+position);
intent.putExtra("tabId", "1");
context.startActivity(intent);
}
}
});
Drawable mDefaultBackground = context.getResources().getDrawable(R.drawable.influencers);
CircularProgressDrawable circularProgressDrawable = new CircularProgressDrawable(context);
circularProgressDrawable.setStrokeWidth(5f);
Glide.with(context)
.load(imageUrl)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
// progressBar.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
// progressBar.setVisibility(View.GONE);
return false;
}
})
.error(mDefaultBackground)
.into(holder.thumbnail);
}else{
//Do whatever you want. Or nothing !!
}
}
#Override
public int getItemCount() {
return postListGlobal.size();
}
class DataViewHolder extends HomeViewHolder {
public DataViewHolder(View itemView) {
super(itemView);
}
}
class ProgressViewHolder extends HomeViewHolder {
public ProgressViewHolder(View itemView) {
super(itemView);
}
}
class HomeViewHolder extends RecyclerView.ViewHolder {
public TextView postTitle, postTime, postWatch, postReaction;
public ImageView thumbnail;
public HomeViewHolder(View itemView) {
super(itemView);
postTitle = itemView.findViewById(R.id.post_title);
postTime = itemView.findViewById(R.id.total_time);
postWatch = itemView.findViewById(R.id.total_watch);
postReaction = itemView.findViewById(R.id.total_reaction);
thumbnail = itemView.findViewById(R.id.thumbnail);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public void addNullData() {
}
public void removeNull() {
notifyItemRemoved(postListGlobal.size());
}
public void addData(List<PostList> postLists) {
postListGlobal.addAll(postLists);
notifyDataSetChanged();
}
}
After trying everything, I was still not able to resolve the issue. Any help/suggestions are welcome. Let me know If I left out any needed code--if so I can update it here.
`postListGlobal.add(postList);` below this line add ` homeFragmentAdapter.notifyDataSetChanged();` and remove ` homeFragmentAdapter.removeNull(); homeFragmentAdapter.addData(postListGlobal);homeFragmentAdapter.notifyDataSetChanged();` this code.Because in this case list added twice without notifying datasetchange check with your code by removing this.
postListGlobal.clear(); just clear tha arraylist before add .
postListGlobal.clear() before adding new list to the adapter.
And then notifyDataSetChanged() to let adapter know of the changes.
I currently have two activities doing HTTP requests.
The first activity contains a CustomList class extends BaseAdapter.
On the second, there is a previous button allowing me to return to the first activity.
Returning to the first activity, I would like to be able to recover the state in which I left it. That is to say to be able to find the information which also come from an HTTP request. I would like to find the data "infos_user" which is in the first activity and all the data in the BaseAdapter.
My architecture is as follows: Activity 0 (HTTP request) -> Activity 1 (with BaseAdapter and HTTP request) -> Activity 2 (HTTP request)
I put all the code because I really don't know how can I do this :/
First activity:
public class GetChildrenList extends AppCompatActivity implements View.OnClickListener {
private ArrayList<Child> childrenImeList = new ArrayList<Child>();
private Button btn_previous;
private ListView itemsListView;
private TextView tv_signin_success;
int id = 0;
String infos_user;
String email;
String password;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.get_children_list);
infos_user = (String) getIntent().getSerializableExtra("infos_user");
Intent intent = new Intent(GetChildrenList.this , GetLearningGoalsList.class);
intent.putExtra("username", infos_user);
btn_previous = (Button) findViewById(R.id.btn_previous);
btn_previous.setOnClickListener(this);
tv_signin_success = (TextView) findViewById(R.id.tv_signin_success);
tv_signin_success.setText("Bonjour " + infos_user + "!");
itemsListView = (ListView)findViewById(R.id.list_view_children);
new GetChildrenAsync().execute();
}
class GetChildrenAsync extends AsyncTask<String, Void, ArrayList<Child>> {
private Dialog loadingDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
loadingDialog = ProgressDialog.show(GetChildrenList.this, "Please wait", "Loading...");
}
#Override
protected ArrayList<Child> doInBackground(String... params) {
int age = 0;
email = (String) getIntent().getSerializableExtra("email");
password = (String) getIntent().getSerializableExtra("password");
String first_name = null;
String last_name = null;
try {
SendRequest sr = new SendRequest();
String result = sr.sendHttpRequest("http://" + sr.getIP_ADDRESS() + "/childrenime/list", "GET", true, email, password);
String jsonResult = "{ \"children\":" + result + "}";
Log.d("result1", jsonResult);
//Manage JSON result
JSONObject jsonObject = new JSONObject(jsonResult);
JSONArray childrenArray = jsonObject.getJSONArray("children");
for (int i = 0; i < childrenArray.length(); ++i) {
JSONObject child = childrenArray.getJSONObject(i);
id = child.getInt("id");
first_name = child.getString("first_name");
last_name = child.getString("last_name");
age = child.getInt("age");
String name = first_name + " " + last_name;
childrenImeList.add(new Child(id,name,age));
}
} catch (JSONException e) {
e.printStackTrace();
}
return childrenImeList;
}
#Override
protected void onPostExecute(final ArrayList<Child> childrenListInformation) {
loadingDialog.dismiss();
if(childrenListInformation.size() > 0) {
CustomListChildrenAdapter adapter = new CustomListChildrenAdapter(GetChildrenList.this, childrenListInformation);
itemsListView.setAdapter(adapter);
}
else{
Toast.makeText(getApplicationContext(), "Impossible de récupérer la liste des enfants", Toast.LENGTH_LONG).show();
}
}
}
}
BaseAdapter:
public class CustomListChildrenAdapter extends BaseAdapter implements View.OnClickListener {
private Context context;
private ArrayList<Child> children;
private Button btnChoose;
private TextView childrenName;
private TextView childrenAge;
public CustomListChildrenAdapter(Context context, ArrayList<Child> children) {
this.context = context;
this.children = children;
}
#Override
public int getCount() {
return children.size(); //returns total item in the list
}
#Override
public Object getItem(int position) {
return children.get(position); //returns the item at the specified position
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.layout_list_view_children,null);
childrenName = (TextView)view.findViewById(R.id.tv_childrenName);
childrenAge = (TextView) view.findViewById(R.id.tv_childrenAge);
btnChoose = (Button) view.findViewById(R.id.btn_choose);
btnChoose.setOnClickListener(this);
} else {
view = convertView;
}
btnChoose.setTag(position);
Child currentItem = (Child) getItem(position);
childrenName.setText(currentItem.getChildName());
childrenAge.setText(currentItem.getChildAge() + "");
return view;
}
#Override
public void onClick(View v) {
Integer position = (Integer) v.getTag();
Child item = (Child) getItem(position);
String email = (String) ((Activity) context).getIntent().getSerializableExtra("email");
String password = (String) ((Activity) context).getIntent().getSerializableExtra("password");
Intent intent = new Intent(context, GetLearningGoalsList.class);
intent.putExtra("idChild",item.getId());
intent.putExtra("email",email);
intent.putExtra("password",password);
context.startActivity(intent);
}
}
Second Activity:
public class GetLearningGoalsList extends AppCompatActivity implements View.OnClickListener {
private ArrayList<LearningGoal> childrenLearningList = new ArrayList<LearningGoal>();
private Button btn_previous;
private ListView itemsListView;
String email;
String password;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.get_learning_goals_list);
btn_previous = (Button) findViewById(R.id.btn_previous);
btn_previous.setOnClickListener(this);
itemsListView = (ListView)findViewById(R.id.list_view_learning_goals);
new GetLearningGoalsAsync().execute();
}
#Override
public void onClick(View v) {
Intent myIntent = new Intent(GetLearningGoalsList.this, GetChildrenList.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
return;
}
class GetLearningGoalsAsync extends AsyncTask<String, Void, ArrayList<LearningGoal>> {
private Dialog loadingDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
loadingDialog = ProgressDialog.show(GetLearningGoalsList.this, "Please wait", "Loading...");
}
#Override
protected ArrayList<LearningGoal> doInBackground(String... params) {
int id = 0;
email = (String) getIntent().getSerializableExtra("email");
password = (String) getIntent().getSerializableExtra("password");
int idChild = (int) getIntent().getSerializableExtra("idChild");
String name = null;
String start_date = null;
String end_date = null;
try {
List<BasicNameValuePair> parameters = new LinkedList<BasicNameValuePair>();
parameters.add(new BasicNameValuePair("idchild", Integer.toString(idChild)));
SendRequest sr = new SendRequest();
String result = sr.sendHttpRequest("http://" + sr.getIP_ADDRESS() + "/learningchild/list"+ "?"+ URLEncodedUtils.format(parameters, "utf-8"), "POST", true, email, password);
String jsonResult = "{ \"learningGoals\":" + result + "}";
Log.d("result1", jsonResult);
//Manage JSON result
JSONObject jsonObject = new JSONObject(jsonResult);
JSONArray learningGoalsArray = jsonObject.getJSONArray("learningGoals");
for (int i = 0; i < learningGoalsArray.length(); ++i) {
JSONObject learningGoal = learningGoalsArray.getJSONObject(i);
id = learningGoal.getInt("id");
name = learningGoal.getString("name");
start_date = learningGoal.getString("start_date");
end_date = learningGoal.getString("end_date");
childrenLearningList.add(new LearningGoal(id,name,start_date,end_date));
}
} catch (JSONException e) {
e.printStackTrace();
}
return childrenLearningList;
}
#Override
protected void onPostExecute(final ArrayList<LearningGoal> learningListInformation) {
loadingDialog.dismiss();
if(learningListInformation.size() > 0) {
CustomListLearningGoalAdapter adapter = new CustomListLearningGoalAdapter(GetLearningGoalsList.this, learningListInformation);
itemsListView.setAdapter(adapter);
}
else{
Toast.makeText(getApplicationContext(), "Impossible de récupérer la liste des scénarios de cet enfant", Toast.LENGTH_LONG).show();
}
}
}
}
Thanks for your help.
if you want to maintain GetChildrenList state as it is then just call finish() rather than new intent on previous button click as follow
replace in GetLearningGoalsList
#Override
public void onClick(View v) {
Intent myIntent = new Intent(GetLearningGoalsList.this, GetChildrenList.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
return;
}
with
#Override
public void onClick(View v) {
finish();
}
I'm developing my app, in which storing quotes.
Data about quotes I download from my server.
I want in order to user downloading 10 quotes (at that time data add to local database), and if he scrolled this 10 quotes, new data will be download (again 10).
For example, as in facebook tape (with adding data to local db).
But I also need sync local db with server db.
I do not understand how to combine all this.
Download data - Here I pass the id from which to download from the id from server db.
class DownloadAndParseJson extends AsyncTask<Integer, Void, ArrayList<QuoteObject>> {
interface AsyncResponse {
void processFinish(ArrayList<QuoteObject> output);
}
private AsyncResponse delegate = null;
DownloadAndParseJson(AsyncResponse delegate){
this.delegate = delegate;
}
private static final String TAG = "###" + "DownloadAndParseJson";
#Override
protected ArrayList<QuoteObject> doInBackground(Integer... params) {
Log.i(TAG, "Starting download quotes from " + params[0] + " id");
if (params.length == 0) {
return null;
}
int id = params[0];
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String countriesJsonStr = null;
try {
final String BASIC_URL = "http://*******.com";
final String ID_PARAM = "id";
Uri builtUri = Uri.parse(BASIC_URL).buildUpon()
.appendQueryParameter(ID_PARAM, Integer.toString(id))
.build();
URL url = new URL(builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
countriesJsonStr = buffer.toString();
Log.v(TAG, "download end");
} catch (IOException e) {
Log.e(TAG, "Error", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(TAG, "Error", e);
}
}
}
Log.i(TAG, "End download quotes");
return getArrayParsedJson(countriesJsonStr);
}
#Override
protected void onPostExecute(ArrayList<QuoteObject> result) {
Log.i(TAG, "Downloaded " + result.size() + " quotes");
delegate.processFinish(result);
}
private ArrayList<QuoteObject> getArrayParsedJson(String jsonStr){
Gson gson = new Gson();
Type collectionType = new TypeToken<ArrayList<QuoteObject>>(){}.getType();
return gson.fromJson(jsonStr, collectionType);
}
}
Working with the database - here Im store Quote objects
public class RealmHelper {
private static final String TAG = "###" + "RealmHelper";
Context context;
public RealmHelper(Context context) {
this.context = context;
}
public void write(ArrayList<QuoteObject> quoteObjectArrayList) {
Realm.init(context);
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
for (QuoteObject quoteObject : quoteObjectArrayList){
realm.copyToRealm(quoteObject);
}
realm.commitTransaction();
}
public ArrayList<QuoteObject> read() {
Realm.init(context);
Realm realm = Realm.getDefaultInstance();
return new ArrayList<>(realm.where(QuoteObject.class).findAll());
}
public void delete() {
Realm.init(context);
Realm realm = Realm.getDefaultInstance();
final RealmResults<QuoteObject> countries = realm.where(QuoteObject.class).findAll();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
countries.deleteAllFromRealm();
Log.i(TAG, "size = " + countries.size());
}
});
}
}
MainActivity
public class MainActivity extends AppCompatActivity
implements DownloadAndParseJson.AsyncResponse{
.
.
RVAdapter adapter;
private ArrayList<QuoteObject> quoteObjectArrayList;
.
.
protected void onCreate(){
.
.
.
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RVAdapter(this, quoteObjectArrayList);
recyclerView.setAdapter(adapter);
}
#Override
public void processFinish(ArrayList<QuoteObject> output) {
if (output.size() != 0) {
quoteObjectArrayList = output;
Log.i(TAG, "processFinish() returned outputArray size " + output.size());
} else
Toast.makeText(this, "Not found quotes", Toast.LENGTH_SHORT).show();
}
RecyclerView.Adapter - To display quotes Im using card view.
class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>
implements DownloadAndParseJson.AsyncResponse{
private static final String TAG = "###" + "RVAdapter";
private Context context;
private boolean hasMoreItems;
private ArrayList<QuoteObject> quoteObjectArrayList;
RVAdapter(Context context, ArrayList<QuoteObject> quoteObjectArrayList){
this.context = context;
this.hasMoreItems = true;
this.quoteObjectArrayList = quoteObjectArrayList;
Log.i(TAG, "quoteObjectArrayList = " + quoteObjectArrayList.size());
}
private void notifyNoMoreItems(){
hasMoreItems = false;
Toast.makeText(context, "No More Items", Toast.LENGTH_SHORT).show();
}
#Override
public RVAdapter.PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.card_of_quote, viewGroup, false);
return new PersonViewHolder(view);
}
#Override
public void onBindViewHolder(final RVAdapter.PersonViewHolder holder, int position) {
Log.i(TAG, "Card position = " + position);
if (position == quoteObjectArrayList.size() && hasMoreItems){
new DownloadAndParseJson(this).execute(Integer.parseInt(quoteObjectArrayList.get(position).getId()));
}
holder.contentOfQuote.setText(quoteObjectArrayList.get(position).getQuote());
holder.authorQuote.setText(quoteObjectArrayList.get(position).getAuthor());
holder.ratingBar.setOnRatingChangeListener(new MaterialRatingBar.OnRatingChangeListener() {
#Override
public void onRatingChanged(MaterialRatingBar ratingBar, float rating) {
//ratingBar.setRight(Integer.parseInt(quoteObjectArrayList.get(position).getId()));
}
});
holder.btnShareQuote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, holder.contentOfQuote.getText()
+ "\n" + holder.authorQuote.getText() );
sendIntent.setType("text/plain");
context.startActivity(sendIntent);
}
});
holder.btnViewComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//View Comments
}
});
}
#Override
public int getItemCount() {
return quoteObjectArrayList.size();
}
#Override
public void processFinish(ArrayList<QuoteObject> output) {
if (output.size() != 0) {
quoteObjectArrayList.addAll(output);
Log.i(TAG, "Total quoteArray Size = " + quoteObjectArrayList.size());
new RealmHelper(context).write(output); // NEED separate throw
} else notifyNoMoreItems();
}
static class PersonViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
TextView contentOfQuote, authorQuote;
MaterialRatingBar ratingBar;
ImageButton btnViewComment, btnShareQuote;
TextView rating;
public PersonViewHolder(View itemView) {
super(itemView);
this.cardView = (CardView) itemView.findViewById(R.id.cardView);
this.contentOfQuote = (TextView) itemView.findViewById(R.id.contentOfQuote);
this.authorQuote = (TextView) itemView.findViewById(R.id.authorQuote);
this.btnViewComment = (ImageButton) itemView.findViewById(R.id.btnViewComment);
this.btnShareQuote = (ImageButton) itemView.findViewById(R.id.btnShareQuote);
this.ratingBar = (MaterialRatingBar) itemView.findViewById(R.id.ratingBar);
this.rating = (TextView) itemView.findViewById(R.id.txtRating);
}
}
}
Now I need to combine all this.
It should turn out:
To start with the data from local db.
If there is no data - download new (10 quotes).
Else take data from local db until they run out
Download 10 quotes from server bd, add to local and display they.
Or If there is no data Print out about it.
Sync local bd with server.
Help me please.
Thanks.
This would be much easier if you used RealmResults as intended along with RealmChangeListener and Realm's notification system. See the official documentation.
class DownloadAndParseJson extends AsyncTask<Integer, Void, Void> {
DownloadAndParseJson(){
}
private static final String TAG = "###" + "DownloadAndParseJson";
#Override
protected Void doInBackground(Integer... params) {
Log.i(TAG, "Starting download quotes from " + params[0] + " id");
if (params.length == 0) {
return null;
}
int id = params[0];
try {
final List<QuoteObject> quotes = retrofitService.getQuotes(id).execute().body();
if(quotes == null) {
throw new RuntimeException("Download failed");
}
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.insert(quotes);
}
});
}
} catch (Exception e) {
Log.e(TAG, "Error", e);
return null;
}
Log.i(TAG, "End download quotes");
return null;
}
#Override
protected void onPostExecute(Void ignored) {
}
}
And
class RVAdapter extends RealmRecyclerViewAdapter<QuoteObject, RVAdapter.PersonViewHolder> {
private static final String TAG = "###" + "RVAdapter";
RVAdapter(OrderedRealmCollection<QuoteObject> quotes) {
super(quotes, true);
}
// onCreateViewHolder
// onBindViewHolder
// view holder
}
And
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new RVAdapter(realm.where(QuotesObject.class).findAll()); // <-- RealmResults
recyclerView.setAdapter(adapter);
and some "did download all" kind of logic, although that needs a bit smarter error handling; and "is data being downloaded" so that you don't spam requests when you scrolled down.
I've this adapter class :
public class NoteFeedListAdapter extends RecyclerView.Adapter<feedItemsHolder>{
private Activity activity;
private LayoutInflater inflater;
private List<NoteFeedItem> feedItems;
private List<CommentModel> commentItems;
private NoteCommentListAdapter adapter;
private RecyclerView mRecyclerView;
ImageLoader imageLoader = NoteAppController.getInstance().getImageLoader();
private static final String URL_LIST_VIEW_COMMENT = "http://url.com";
private int level = 0;
private Context mContext;
public NoteFeedListAdapter(Context context, List<NoteFeedItem> feedItems) {
this.feedItems = feedItems;
this.mContext = context;
}
public feedItemsHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.feed_item, null);
feedItemsHolder mh = new feedItemsHolder(v);
return mh;
}
public void onBindViewHolder(final feedItemsHolder fItemsHolder, final int i) {
final NoteFeedItem item = feedItems.get(i);
fItemsHolder.setLevel(item.getLevel());
if (item.getName2() != null) {
fItemsHolder.mHiddenComment.setText(item.getName2()+": "+item.getComment2());
fItemsHolder.feedImageView.setVisibility(View.VISIBLE);
and Inside onBindViewHolder :
int jComment = Integer.parseInt(item.getJumlahComment().toString());
if( jComment > 0){
fItemsHolder.mHiddenComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//this code is what I used to call asyntask but result from asynctask cannot be shown in this adapter
commentItems = new ArrayList<CommentModel>();
adapter = new NoteCommentListAdapter(mContext, commentItems);
mRecyclerView = new RecyclerView(mContext);
getListViewComments(item.getUserid(), item.getId(),fItemsHolder,i, commentItems, adapter, mRecyclerView);
commentItems = new ArrayList<CommentModel>();
adapter = new NoteCommentListAdapter(mContext, commentItems);
mRecyclerView.setAdapter(adapter);
}
});
}
...
} else {
fItemsHolder.mHiddenComment.setVisibility(View.GONE);
fItemsHolder.mLinearHiddenComment.setVisibility(View.GONE);
}
if(item.getLevel() == Level.LEVEL_ONE){
level = Level.LEVEL_TWO;
}else if(item.getLevel() == Level.LEVEL_TWO){
level = Level.LEVEL_THREE;
}
}
public int getItemCount() {
return (null != feedItems ? feedItems.size() : 0);
}
private void getListViewComments(final String userid, String id_note,final feedItemsHolder feedItemsHolder, int i, final List<CommentModel> commentItems, final NoteCommentListAdapter adapter, final RecyclerView mRecyclerView) {
class ambilComment extends AsyncTask<String, Void, String> {
ProgressDialog loading;
com.android.personal.asynctask.profileSaveDescription profileSaveDescription = new profileSaveDescription();
String result = "";
InputStream inputStream = null;
#Override
protected void onPreExecute() {
feedItemsHolder.mLoading.setVisibility(View.GONE);
feedItemsHolder.mHiddenComment.setVisibility(View.GONE);
feedItemsHolder.mLinearHiddenComment.setVisibility(View.GONE);
feedItemsHolder.mLoading.setVisibility(View.VISIBLE);
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
HashMap<String, String> data = new HashMap<String,String>();
data.put("userid", params[0]);
data.put("id_note", params[1]);
String result = profileSaveDescription.sendPostRequest(URL_LIST_VIEW_COMMENT,data);
return result;
}
protected void onPostExecute(String s) {
JSONArray dataJsonArr = null;
if(s.equals(null)){
Toast.makeText(mContext, "Internet Problem.", Toast.LENGTH_SHORT).show();
}else{
try{
JSONObject json = new JSONObject(s);
String id_note = json.getString("id_note");
Toast.makeText(mContext, id_note, Toast.LENGTH_SHORT).show();
dataJsonArr = json.getJSONArray("data");
for (int i = 0; i < dataJsonArr.length(); i++) {
JSONObject c = dataJsonArr.getJSONObject(i);
String id_comment = c.getString("id_comment");
String uid = c.getString("userid");
String profile_name = c.getString("profile_name");
String profile_photo = c.getString("profile_photo");
String amount_of_like = c.getString("amount_of_like");
String amount_of_dislike = c.getString("amount_of_dislike");
String amount_of_comment = c.getString("amount_of_comment");
String content_comment = c.getString("content_comment");
String tgl_comment = c.getString("tgl_comment");
String parent_id = c.getString("parent_id");
CommentModel citem = new CommentModel();
citem.setId_note(id_note);
citem.setId_comment(id_comment);
citem.setUserid(uid);
citem.setProfileName(profile_name);
String pPhoto = c.isNull("profile_photo") ? null : c.getString("profile_photo");
citem.setProfile_photo(pPhoto);
citem.setJumlahLove(amount_of_like);
citem.setJumlahNix(amount_of_dislike);
citem.setJumlahComment(amount_of_comment);
citem.setContent_comment(content_comment);
citem.setTimeStamp(tgl_comment);
String prntID = c.isNull("parent_id") ? null : c.getString("parent_id");
citem.setParent_id(prntID);
citem.setLevel(level);
commentItems.add(citem);
}
adapter.notifyDataSetChanged();
}catch(JSONException e){
e.printStackTrace();
Log.w("getListNotesComment", "exception");
}
}
/* iH.mHiddenComment.setText("");*/
}
}
ambilComment ru = new ambilComment();
ru.execute(userid, id_note);
}
The problem is that I wanna add data from Asynctask and shown on another adapter. But how can i do that? please help. view from another adapter couldn't show with this code.
I have, below the following fragment that populates a gridview with Bitmaps from URLs. The problem is that I know it's very 'heavy' work and done on the UI Thread so it's slowing the fragment down when loading the grid.
I've read that an AsyncTask is needed to carry out the 'heavy' work in the background but I can't find anything that seems to fit with what I want.
public class HomeFragment extends Fragment {
protected static final String TAG = null;
public HomeFragment(){}
GridView gridView;
private GridViewAdapter gridAdapter;
private SQLiteHandler db;
private SwipeRefreshLayout swipeLayout;
private ProgressDialog pDialog;
GPSTracker gps;
String uid;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
db = new SQLiteHandler(getActivity());
gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_item_layout, getData());
pDialog = new ProgressDialog(getActivity());
pDialog.setCancelable(true);
uid="1";
String email = db.getFromTable(getActivity(), "email", SQLiteHandler.TABLE_LOGIN, "WHERE _id="+uid);
String from_age = db.getFromTable(getActivity(), "from_age", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String to_age = db.getFromTable(getActivity(), "to_age", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String distance = db.getFromTable(getActivity(), "distance", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String unit = db.getFromTable(getActivity(), "unit", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String men = db.getFromTable(getActivity(), "men", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String women = db.getFromTable(getActivity(), "women", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
fetchUsers(email, from_age, to_age, distance, unit, men, women);
final View rootView = inflater.inflate(R.layout.fragment_home, container, false);
//getActivity().getActionBar().setTitle(R.string.home);
gridView = (GridView) rootView.findViewById(R.id.gridView);
gridView.setAdapter(gridAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageItem item = (ImageItem) parent.getItemAtPosition(position);
ImageView imageView = (ImageView) v.findViewById(R.id.image);
//Create intent
Intent intent = new Intent(getActivity(), DetailsActivity.class);
int[] screenLocation = new int[2];
imageView.getLocationOnScreen(screenLocation);
intent.putExtra("left", screenLocation[0]).
putExtra("top", screenLocation[1]).
putExtra("width", imageView.getWidth()).
putExtra("height", imageView.getHeight()).
putExtra("uid", item.getUid());
startActivity(intent);
}
});
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
//my update process
Fragment currentFragment = getFragmentManager().findFragmentByTag("0");
FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
fragTransaction.detach(currentFragment);
fragTransaction.attach(currentFragment);
fragTransaction.commit();
}
});
return rootView;
}
// Prepare some dummy data for gridview
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
Cursor cursor = db.getAllRows("*", SQLiteHandler.TABLE_USERS, "");
//Query local DB to initialize settings screen
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
String uid = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_UID));
String name = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_NAME));
String dob = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_DOB));
//String gender = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_GENDER));
String photourl = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_PHOTOURL));
//String distance = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_DISTANCE));
String[] birthdayArr = dob.split("-");
int age = getAge(Integer.parseInt(birthdayArr[0]), Integer.parseInt(birthdayArr[1]), Integer.parseInt(birthdayArr[2]));
Bitmap bitmap = getBitmapFromURL(photourl);
imageItems.add(new ImageItem(bitmap, name+" - " + age, uid));
}
return imageItems;
}
public static Bitmap getBitmapFromURL(String src) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
// Log exception
return null;
}
}
public int getAge(int year, int month, int day) {
//int nowMonth = now.getMonth()+1;
int nowMonth = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
//int nowYear = now.getYear()+1900;
int nowYear = Calendar.getInstance().get(Calendar.YEAR);
int result = nowYear - year;
if (month > nowMonth) {
result--;
}
else if (month == nowMonth) {
int nowDay = Calendar.getInstance().get(Calendar.DATE);
if (day > nowDay) {
result--;
}
}
return result;
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
Log.i("hideDialog", "called");
if (pDialog.isShowing())
pDialog.dismiss();
}
public void fetchUsers(final String email, final String agefrom, final String ageto, final String distance, final String distanceUnit, final String interested_men, final String interested_wmen){
// Tag used to cancel the request
gps = new GPSTracker(getActivity());
String tag_string_req = "req_login";
pDialog.setMessage("Finding users ...");
showDialog();
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_LOGIN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Fetch Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
int success = jObj.getInt("success");
JSONArray users = jObj.getJSONArray("users");
// Check for error node in json
if (success == 1) {
//Log.i("success", users+"");
if (users.length() == 0) {
Toast.makeText(getActivity(), "No users found! \nPlease try again soon.", Toast.LENGTH_LONG).show();
db.emptyTable(SQLiteHandler.TABLE_USERS);
}else{
db.emptyTable(SQLiteHandler.TABLE_USERS);
for (int i = 0; i < users.length(); i++) {
JSONObject user = users.getJSONObject(i);
String uid = user.getString("uid");
String name = user.getString("name");
String dob = user.getString("dob");
String gender = user.getString("gender");
String photourl = user.getString("photoUrl");
String distance = user.getString("distance");
String[][] userValues = {
{ SQLiteHandler.KEY_UID, uid},
{ SQLiteHandler.KEY_NAME, name},
{ SQLiteHandler.KEY_DOB, dob},
{ SQLiteHandler.KEY_GENDER, gender},
{ SQLiteHandler.KEY_PHOTOURL, photourl},
{ SQLiteHandler.KEY_DISTANCE, distance}
};
db.insert(SQLiteHandler.TABLE_USERS, userValues);
}
}
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getActivity(),errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getActivity(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
//$lat, $lng, $email, $agefrom, $ageto, $distance, $distanceUnit, $interested_men, $interested_wmen
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "login");
params.put("lat", gps.getLatitude()+"");
params.put("lng", gps.getLongitude()+"");
params.put("email", email);
params.put("agefrom", agefrom);
params.put("ageto", ageto);
params.put("distance", distance);
params.put("distanceUnit", distanceUnit);
params.put("interested_men", interested_men+"");
params.put("interested_wmen", interested_wmen+"");
params.put("fetch", "y");
Log.i(TAG, params+"");
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
}
How to load GridView images with AsyncTask?
Downloading images as Bitmap in HomeFragment. Use NetworkImageView from Volley in layout of GridView item for loading images in GridView.
Instead of storing Bitmap, store image url in ImageItem.
See following tutorial for more help:
Using NetworkImageView
AsynTask class
public class GridDataAsyncTask extends AsyncTask<GridDataAsyncTask.GridCallback, Void, GridAdapter> {
public interface GridCallback {
void onAdapterReady(GridAdapter adapter);
}
private GridCallback mCallBack;
#Override
protected GridAdapter doInBackground(GridCallback... callbacks) {
mCallBack = callbacks[0];
// TODO get data and create grid adapter
return adapter;
}
#Override
protected void onPostExecute(GridAdapter gridAdapter) {
super.onPostExecute(gridAdapter);
mCallBack.onAdapterReady(gridAdapter);
}
}
Activity
public class GridActivity extends AppCompatActivity implements GridDataAsyncTask.GridCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new GridDataAsyncTask().execute(this);
}
#Override
public void onAdapterReady(GridAdapter adapter) {
// TODO set adapte to GridView
}
}
Best you can do is use http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html and make a lru cache and place the images in lru cache.
Example is given in android tutorials
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
As suggested by fractalwrench and Budius, Picasso was a very good and VERY easy solution to this. All I had to do was to pass the photo url instead of the entire BitMap through to my GridView adapter and use Picasso.with(context).load(item.getImage()).into(holder.image); to create the BitMap for the image view. This was so easy to implement and gives me exactly what I need. Thaks