我使用restapi为Android中的应用程序提供数据,对于数据库我使用phpmyadmin并在localhost中执行,一切顺利,但是当我在数据库中添加新数据时recycleview
无法同步使用数据库中的最新数据,因此当我滑动或滚动我刚刚添加的最新数据时,我recycleview
中的数据显示为double,它将永远不会结束。我正在使用模拟器来运行apk。
如果有人可以帮我修改我的代码,我真的很感激。这是我的customVolleyRequest
代码:
public class CustomVolleyRequest {
private static CustomVolleyRequest customVolleyRequest;
private static Context context;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private CustomVolleyRequest(Context context) {
this.context = context;
this.requestQueue = getRequestQueue();
imageLoader = new ImageLoader(requestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized CustomVolleyRequest getInstance(Context context) {
if (customVolleyRequest == null) {
customVolleyRequest = new CustomVolleyRequest(context);
}
return customVolleyRequest;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
Cache cache = new DiskBasedCache(context.getCacheDir(), 10 * 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
requestQueue = new RequestQueue(cache, network);
requestQueue.start();
}
return requestQueue;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
这是我的appconfig
类用于存储标记:
public class AppConfig {
// Server user login url
public static String URL_LOGIN = "http://192.168.0.13:80/task_manager/v1/login";
// Server user register url
public static String URL_REGISTER = "http://192.168.0.13/task_manager/v1/register";
//URL of my even
public static final String DATA_URL = "http://192.168.0.13/task_manager/v1/even/";
//Tags for my JSON
public static final String TAG_IMAGE_URL = "gambar";
public static final String TAG_JUDUL = "judul";
public static final String TAG_DESKRIPSI = "deskripsi";
public static final String TAG_DUIT = "duit";
public static final String TAG_PERSEN = "persen";
public static final String TAG_SISA_HARI = "sisahari";
}
这是getter和setter:
public class Event {
//Data Variables
private String imageUrl;
private String name;
private String rank;
private int realName;
private int createdBy;
private int firstAppearance;
//private ArrayList<String> powers;
//Getters and Setters
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
//GET AND SET JUDUL
public String getJudul() {
return name;
}
public void setJudul(String name) {
this.name = name;
}
//GET AND SET DESKRIPSI
public String getDeskripsi() {
return rank;
}
public void setDeskripsi(String rank) {
this.rank = rank;
}
//GET AND SET DUIT
public int getDuit() {
return realName;
}
public void setDuit(int realName) {
this.realName = realName;
}
//GET AND SET PERSEN
public int getPersen() {
return createdBy;
}
public void setPersen(int createdBy) {
this.createdBy = createdBy;
}
//GET AND SET SISA HARI
public int getSisaHari() {
return firstAppearance;
}
public void setSisaHari(int firstAppearance) {
this.firstAppearance = firstAppearance;
}
}
这是我的主要片段:
package com.anakacara.anakacara.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.anakacara.anakacara.App.AppConfig;
import com.anakacara.anakacara.App.Event;
import com.anakacara.anakacara.Helper.CardAdapter;
import com.anakacara.anakacara.R;
import com.anakacara.anakacara.activity.DetailEvent;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link EventFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link EventFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class EventFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
// 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";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
//Creating a List of event
private List<Event> listEvent;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private int requestCount = 1;
private int list;
private OnFragmentInteractionListener mListener;
private RequestQueue requestQueue;
private ProgressBar progressBar;
private SwipeRefreshLayout swipeRefreshLayout;
public EventFragment() {
// 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 EventFragment.
*/
// TODO: Rename and change types and number of parameters
public static EventFragment newInstance(String param1, String param2) {
EventFragment fragment = new EventFragment();
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);
}
}
private final RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
// code
}
@Override
public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) {
// code
if (isLastItemDisplaying(recyclerView)) {
//Calling the method getdata again
getData();
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View x = inflater.inflate(R.layout.fragment_event,null);;
progressBar = (ProgressBar) x.findViewById(R.id.progressBar1);
recyclerView = (RecyclerView) x.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
listEvent = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity());
swipeRefreshLayout = (SwipeRefreshLayout) x.findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
getData();
}
}
);
// listEvent = new ArrayList<>();
// requestQueue = Volley.newRequestQueue(getActivity());
//Calling method to get data
//this method is called twice as if you see
// getData();
// swipeRefreshLayout= (SwipeRefreshLayout) x.findViewById(R.id.swipeRefreshLayout);
// swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
// {
// @Override
// public void onRefresh()
// {
// if (isLastItemDisplaying(recyclerView)) {
////Calling the method getdata again
// getData();
// progressBar.setVisibility(View.GONE);
// }
// }
// });
recyclerView.addOnScrollListener(rVOnScrollListener);
adapter = new CardAdapter(listEvent, getActivity());
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setAddDuration(1000);
itemAnimator.setRemoveDuration(1000);
recyclerView.setItemAnimator(itemAnimator);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
Intent intent = new Intent(getActivity(), DetailEvent.class);
intent.putExtra("event_judul", listEvent.get(position).getJudul()); //you can name the keys whatever you like
intent.putExtra("event_deskripsi", listEvent.get(position).getDeskripsi()); //note that all these values have to be primitive (i.e boolean, int, double, String, etc.)
intent.putExtra("event_duit", listEvent.get(position).getDuit());
intent.putExtra("event_persen", listEvent.get(position).getPersen()); //note that all these values have to be primitive (i.e boolean, int, double, String, etc.)
intent.putExtra("event_sisa_hari", listEvent.get(position).getSisaHari());
intent.putExtra("event_image", listEvent.get(position).getImageUrl());
startActivity(intent);
}
@Override
public void onLongClick(View view, int position) {
Toast.makeText(getActivity(), "Kepencet Lama " + position, Toast.LENGTH_LONG).show();
}
}));
return x;
}
private JsonArrayRequest getDataFromServer(int requestCount) {
//Initializing ProgressBar
swipeRefreshLayout.setRefreshing(true);
//Displaying Progressbar
progressBar.setVisibility(View.VISIBLE);
// getActivity().getParent().setProgressBarIndeterminateVisibility(true);
//JsonArrayRequest of volley
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(AppConfig.DATA_URL + String.valueOf(requestCount),
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
//Calling method parseData to parse the json response
parseData(response);
//Hiding the progressbar
progressBar.setVisibility(View.GONE);
swipeRefreshLayout.setRefreshing(false);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
//If an error occurs that means end of the list has reached
Toast.makeText(getActivity(), "No More Items Available"+list, Toast.LENGTH_SHORT).show();
swipeRefreshLayout.setRefreshing(false);
}
});
//Returning the request
return jsonArrayRequest;
}
private void getData() {
//Adding the method to the queue by calling the method getDataFromServer
requestQueue.add(getDataFromServer(requestCount));
//Incrementing the request counter
}
//This method will parse json data
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
Event event = new Event();
JSONObject json = null;
try {
json = array.getJSONObject(i);
event.setJudul(json.getString(AppConfig.TAG_JUDUL));
event.setDeskripsi(json.getString(AppConfig.TAG_DESKRIPSI));
event.setDuit(json.getInt(AppConfig.TAG_DUIT));
event.setPersen(json.getInt(AppConfig.TAG_PERSEN));
event.setSisaHari(json.getInt(AppConfig.TAG_SISA_HARI));
event.setImageUrl(json.getString(AppConfig.TAG_IMAGE_URL));
event.setTotal(json.getInt(AppConfig.TAG_TOTAL));
} catch (JSONException e) {
e.printStackTrace();
}
listEvent.add(event);
}
adapter.notifyDataSetChanged();
if( requestCount <= listEvent.get(0).getTotal()) {
requestCount++;
}
//Finally initializing our adapter
}
// 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;
}
@Override
public void onRefresh() {
if (isLastItemDisplaying(recyclerView)) {
getData();
}
}
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private GestureDetector mGestureDetector;
private ClickListener mClickListener;
public RecyclerTouchListener(final Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.mClickListener = clickListener;
mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(),e.getY());
if (child!=null && clickListener!=null){
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
}
super.onLongPress(e);
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child!=null && mClickListener!=null && mGestureDetector.onTouchEvent(e)){
mClickListener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
private RecyclerView.OnScrollListener rVOnScrollListener = new RecyclerView.OnScrollListener(){
@Override
public void onScrollStateChanged(RecyclerView recyclerView,
int newState) {
super.onScrollStateChanged(recyclerView, newState);
// Toast.makeText(getApplicationContext(),
// Config.DATA_URL+String.valueOf(requestCount), Toast.LENGTH_LONG).show();
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isLastItemDisplaying(recyclerView)) {
//Calling the method getdata again
getData();
progressBar.setVisibility(View.GONE);
}
}
};
public static interface ClickListener{
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
/**
* 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);
}
}
这是我的适配器:
package com.anakacara.anakacara.Helper;
/**
* Created by Philipus on 05/03/2016.
*/
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.anakacara.anakacara.App.CustomVolleyRequest;
import com.anakacara.anakacara.App.Event;
import com.anakacara.anakacara.R;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import java.util.List;
/**
* Created by Belal on 11/9/2015.
*/
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
private ImageLoader imageLoader;
private Context context;
//List of eventes
List<Event> eventes;
public CardAdapter(List<Event> eventes, Context context){
super();
//Getting all the eventA
this.eventes = eventes;
this.context = context;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.event_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Event event = eventes.get(position);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(event.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));
holder.imageView.setImageUrl(event.getImageUrl(), imageLoader);
holder.textViewJudul.setText(event.getJudul());
holder.textViewRank.setText(event.getDeskripsi());
holder.textViewRealName.setText(String.valueOf(event.getDuit()));
holder.textViewCreatedBy.setText(String.valueOf(event.getPersen()));
holder.textViewFirstAppearance.setText(String.valueOf(event.getSisaHari()));
}
@Override
public int getItemCount() {
return eventes.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView imageView;
public TextView textViewJudul;
public TextView textViewRank;
public TextView textViewRealName;
public TextView textViewCreatedBy;
public TextView textViewFirstAppearance;
// public TextView textViewPowers;
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewJudul = (TextView) itemView.findViewById(R.id.textViewJudul);
textViewRank= (TextView) itemView.findViewById(R.id.textViewRank);
textViewRealName= (TextView) itemView.findViewById(R.id.textViewRealName);
textViewCreatedBy= (TextView) itemView.findViewById(R.id.textViewCreatedBy);
textViewFirstAppearance= (TextView) itemView.findViewById(R.id.textViewFirstAppearance);
}
}
}
答案 0 :(得分:0)
使用Volley队列的onRequestFinishedLitener来更改通知数据集。
class RequestListener implements RequestQueue.RequestFinishedListener {
@Override
public void onRequestFinished(Request request) {
adapter.notifyDatasetChanged();
}
}
然后
RequestListener rl = new RequestListener();
volley_queue.addRequestFinishedListener(listener);
如果要在列表结束时加载新数据。您将不得不在您的API中创建位于服务器上的页面。你必须逐页访问。根据列表到达结束,您将调用parseJson作为下一页。
您将使用包含下一个数据的新链接调用您的parseJSON方法。为此,您将添加ReyclerView的OnScrollListener。
class RecyclerViewOnScroll extends RecyclerView.OnScrollListener
{
int temp_page_position;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if ((list.size()-1 == layoutManager.findLastVisibleItemPosition())) {
// Enters to block when last item of RecyclerView has appeared.
}
}
}