So I put an images inside of gridview, it works fine when the beginning and showing 20 images but when I try to show less than that it won't updated.
there are a condition when the gridview updated, it's updated when I load 20 images but when I try to load less or zero it wont updated.
how do I resolve this ?
here is my code on the adapter
private final Context context;
private List<Movie> urls = new ArrayList<>();
public MovieGridViewAdapter(Context context, List<Movie> urls) {
this.context = context;
this.urls = urls;
}
#Override
public int getCount() {
if (urls.size() == 0){
return 0;
}
return urls.size();
}
#Override
public Movie getItem(int position) {
return urls.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
View gridView = view;
if (gridView == null) {
gridView = LayoutInflater.from(context)
.inflate(R.layout.item_poster, viewGroup, false);
}
ImageView posterImageView = (ImageView) gridView.findViewById(R.id.posterImageView);
// Get the image URL for the current position.
Movie movie = getItem(position);
//needed to append the image url
String imageBaseUrl = "http://image.tmdb.org/t/p/w185";
Picasso.with(context) //
.load(imageBaseUrl+movie.getPosterPath()) //
.placeholder(R.drawable.ic_hourglass_empty_black_24dp) //
.error(R.drawable.ic_error_black_24dp) //
.fit() //
.tag(context) //
.into(posterImageView);
Log.v("jalan ji", "jalan");
return gridView;
}
here is where I try to update the Gridview
List<Favorite> favorites = new ArrayList<>();
Cursor cursor = getContentResolver().query(MovieContract.MovieEntry.CONTENT_URI,
null,
null,
null,
MovieContract.MovieEntry.COLUMN_TITLE);
while(cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_MOVIE_ID));
String title = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_TITLE));
try{
Favorite fav = new Favorite();
fav.setId(id);
fav.setTitle(title);
favorites.add(fav);
}catch (Exception e){
e.printStackTrace();
}
}
for(Favorite favorite : favorites){
Call<MovieSingle> call = movieDbClient.getMovie(favorite.getId(), apiKey);
setTitle("Favorite Movies");
call.enqueue(new Callback<MovieSingle>() {
#Override
public void onResponse(#NonNull Call<MovieSingle> call, #NonNull Response<MovieSingle> response) {
Movie mov = new Movie();
mov.setBackdropPath(response.body().getBackdrop_path());
mov.setOverview(response.body().getOverview());
mov.setReleaseDate(response.body().getRelease_date());
mov.setTitle(response.body().getTitle());
mov.setVoteAverage(response.body().getVote_average());
mov.setPosterPath(response.body().getPoster_path());
movie.add(mov);
Log.v("berhasil", " "+response.body().getTitle());
}
#Override
public void onFailure(#NonNull Call<MovieSingle> call, #NonNull Throwable t) {
t.printStackTrace();
pbar.setVisibility(View.INVISIBLE);
Log.v("gagal", "berhasil");
showErrorMessage();
}
});
}
showGridView();
pbar.setVisibility(View.INVISIBLE);
MovieGridViewAdapter movieGridViewAdapter = new MovieGridViewAdapter(getApplicationContext(), movie);
Log.v("Test", movie.get(2).getTitle());
Log.v("Test", movie.get(2).getPosterPath());
movieGridViewAdapter.notifyDataSetChanged();
gridView.invalidateViews();
gridView.setAdapter(movieGridViewAdapter);
and the layout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bgdetail">
<GridView android:id="#+id/movieitem_grid"
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="165dp"
android:scrollbarStyle="insideOverlay"
android:scrollbars="none"
android:listSelector="#null"
android:numColumns="auto_fit"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_error"
android:layout_gravity="center"
android:textAlignment="center"
android:textColor="#color/textColor"
android:text="#string/error_msg"
android:visibility="invisible"
android:textSize="22sp"/>
<ProgressBar
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_gravity="center"
android:id="#+id/progressbar"
android:visibility="invisible"/>
</FrameLayout>
Solved, I have to put the setAdapter method inside the loop and create new variable of list and make it final, can't use the global one. so the final code should look like this
List<Favorite> favorites = new ArrayList<>();
final List<Movie> movie1 = new ArrayList<>();
Cursor cursor = getContentResolver().query(MovieContract.MovieEntry.CONTENT_URI,
null,
null,
null,
MovieContract.MovieEntry.COLUMN_TITLE);
while(cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_MOVIE_ID));
String title = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_TITLE));
try{
Favorite fav = new Favorite();
fav.setId(id);
fav.setTitle(title);
favorites.add(fav);
}catch (Exception e){
e.printStackTrace();
}
}
for(Favorite favorite : favorites){
Call<MovieSingle> call = movieDbClient.getMovie(favorite.getId(), apiKey);
setTitle("Favorite Movies");
call.enqueue(new Callback<MovieSingle>() {
#Override
public void onResponse(#NonNull Call<MovieSingle> call, #NonNull Response<MovieSingle> response) {
Movie mov = new Movie();
mov.setBackdropPath(response.body().getBackdrop_path());
mov.setOverview(response.body().getOverview());
mov.setReleaseDate(response.body().getRelease_date());
mov.setTitle(response.body().getTitle());
mov.setVoteAverage(response.body().getVote_average());
mov.setPosterPath(response.body().getPoster_path());
movie1.add(mov);
showGridView();
pbar.setVisibility(View.INVISIBLE);
MovieGridViewAdapter movieGridViewAdapter = new MovieGridViewAdapter(getApplicationContext(), movie1);
movieGridViewAdapter.notifyDataSetChanged();
gridView.setAdapter(movieGridViewAdapter);
Log.v("berhasil", " "+movie1.get(0).getTitle());
}
#Override
public void onFailure(#NonNull Call<MovieSingle> call, #NonNull Throwable t) {
t.printStackTrace();
pbar.setVisibility(View.INVISIBLE);
Log.v("gagal", "berhasil");
showErrorMessage();
}
});
}
Related
I have a problem, when i swipe to refresh the data, the first swipe is ok but after that every swipe reload and add the same data over and over again, by the end i have a list with same items over and over... I'm using a loader. I tried to clear before but i don't understand what's wrong with my code, if someone could explain it to me. Thank You.
Here my code :
public static final String EXTRA_URL = "imageUrl";
public static final String EXTRA_APKNAME = "apkname";
public static final String EXTRA_APKSIZE = "apksize";
public static final String EXTRA_APKFILE = "apkfile";
private RecyclerView mRecyclerView;
private MyAdapter mExampleAdapter;
private ArrayList<one_item> mExampleList;
private RequestQueue mRequestQueue;
private SwipeRefreshLayout swipeRefreshLayout;
#SuppressLint("RestrictedApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("APK VIP CHINA");
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
swipeRefreshLayout = findViewById(R.id.refreshlayout);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mExampleList = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
parseJSON();
swipeRefreshLayout.setRefreshing(false);
}
});
}
private void parseJSON() {
String url = "http://apkvip.net/json2.php";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String creatorName = hit.getString("ten");
String creatorsize = hit.getString("apk_size");
String creatorfile = hit.getString("link_apk");
String imageUrl = hit.getString("link_img");
mExampleList.add(new one_item(imageUrl, creatorName, creatorsize, creatorfile));
}
mExampleAdapter = new MyAdapter(MainActivity.this, mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
mExampleAdapter.setOnItemClickListener(MainActivity.this);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
public void onItemClick(int position) {
Intent detailIntent = new Intent(this, activity_detail.class);
one_item clickedItem = mExampleList.get(position);
detailIntent.putExtra(EXTRA_URL, clickedItem.getmImageUrl());
detailIntent.putExtra(EXTRA_APKNAME, clickedItem.getMapkname());
detailIntent.putExtra(EXTRA_APKSIZE, clickedItem.getMapksize());
detailIntent.putExtra(EXTRA_APKFILE, clickedItem.getMapkfile());
startActivity(detailIntent);
}}
My adapter:
private ArrayList<one_item> mExampleList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public MyAdapter(Context context, ArrayList<one_item> exampleList) {
mContext = context;
mExampleList = exampleList;
}
#Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.one_item, parent, false);
return new ExampleViewHolder(v);
}
#Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
one_item currentItem = mExampleList.get(position);
String imageUrl = currentItem.getmImageUrl();
String apkname = currentItem.getMapkname();
String apksize = currentItem.getMapksize();
String apkfile = currentItem.getMapkfile();
holder.mTextViewname.setText(apkname);
holder.mTextViewsize.setText(apksize);
holder.mTextViewfile.setText(apkfile);
Picasso.get().load(imageUrl).fit().centerInside().into(holder.mImageView);
}
#Override
public int getItemCount() {
return mExampleList.size();
}
#Override
public long getItemId(int position) {
return position;
}
public class ExampleViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextViewname, mTextViewsize, mTextViewfile;
public ExampleViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.image);
mTextViewname = itemView.findViewById(R.id.name);
mTextViewsize = itemView.findViewById(R.id.size);
mTextViewfile = itemView.findViewById(R.id.file);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
});}}}
my activitymain.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Recommended Apps"
android:textColor="#000"
android:textStyle="bold"
android:textSize="20sp"
android:layout_marginBottom="10dp"
/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/refreshlayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:padding="5dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Just use mExampleList.clear() at the first line of your parseJSON() function
and then you'll be able to add the "updated" items.
In addition I'd suggest that you move swipeRefreshLayout.setRefreshing(false) to the end of Volley onResponse and onError() implementation -
Right now you're telling the swipeRefreshLayout to stop refreshing before the request(that happens asynchronously) has finished
You are initializing your adapter every time you do a swipe.
Change this constructor of MyAdapter code.
public MyAdapter(Context context, ArrayList<one_item> exampleList) {
mContext = context;
mExampleList = exampleList;
}
to,
public MyAdapter(Context context) {
mContext = context;
}
public setExampleList(ArrayList<one_item> exampleList){
mExampleList = exampleList;
}
Now change your onCreate function to.
#SuppressLint("RestrictedApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("APK VIP CHINA");
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
swipeRefreshLayout = findViewById(R.id.refreshlayout);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mExampleList = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
//Changed Code
mExampleAdapter = new MyAdapter(MainActivity.this);
mRecyclerView.setAdapter(mExampleAdapter);
mExampleAdapter.setOnItemClickListener(MainActivity.this);
parseJSON();
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
parseJSON();
swipeRefreshLayout.setRefreshing(false);
}
});
}
private void parseJSON() {
String url = "http://apkvip.net/json2.php";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String creatorName = hit.getString("ten");
String creatorsize = hit.getString("apk_size");
String creatorfile = hit.getString("link_apk");
String imageUrl = hit.getString("link_img");
mExampleList.add(new one_item(imageUrl, creatorName, creatorsize, creatorfile));
}
//Changed Code
mExampleAdapter.setExampleList(mExampleList);
mExampleAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
I have added a comment of the code block where I have made the changes.
Feel free to comment in case you have any queries.
https://launchlibrary.net/1.3/launch shows json data. If you paste the id after this url, there is more in depth information about the launch, for example https://launchlibrary.net/1.3/launch/2053.
I want to get the image url of the corresponding launch but it doesn't work how I'm doing it. This is the code from where I parse the JSON data.
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.activity_launches, container, false);
myRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
myRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
launchesList = new ArrayList<>();
temporaryList = new ArrayList<>();
myRequestQueue = Volley.newRequestQueue(getContext());
parseJSON();
return v;
}
private void parseJSON(){
String url = "https://launchlibrary.net/1.3/launch";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("launches");
for(int i = 0; i < jsonArray.length(); i++){
JSONObject launch = jsonArray.getJSONObject(i);
String launchName = launch.getString("name");
String launchDate = launch.getString("net");
launchId = launch.getString("id");
String imageUrl = getImageUrl();
Launch newLaunch = new Launch(launchName, launchDate, imageUrl);
launchesList.add(newLaunch);
}
myRecyclerViewAdapter = new RecyclerViewAdapter(getContext(), launchesList);
myRecyclerView.setAdapter(myRecyclerViewAdapter);
myRecyclerViewAdapter.setOnItemClickListener(LaunchesActivity.this);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
myRequestQueue.add(request);
}
public String getImageUrl(){
String url = "https://launchlibrary.net/1.3/launch/" + launchId;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("launches");
JSONObject launch = jsonArray.getJSONObject(0);
JSONObject rocket = launch.getJSONObject("rocket");
String url = rocket.getString("imageURL");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
myRequestQueue.add(request);
return url;
}
This is the adapter I created to change the text in the TextViews and ImageView.
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder>{
private Context myContext;
private ArrayList<Launch> launchList;
private OnItemClickListener myListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
myListener = listener;
}
public RecyclerViewAdapter(Context context, ArrayList<Launch> launchList){
myContext = context;
this.launchList = launchList;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(myContext).inflate(R.layout.launch_item, parent, false);
return new RecyclerViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
Launch currentItem = launchList.get(position);
String name = currentItem.getName();
String date = currentItem.getDate();
String imageUrl = currentItem.getImageUrl();
holder.myTextViewName.setText(name);
holder.myTextViewDate.setText(date);
Picasso.get().load(imageUrl).fit().centerInside().into(holder.myImageViewImage);
}
#Override
public int getItemCount() {
return launchList.size();
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder{
public TextView myTextViewName;
public TextView myTextViewDate;
public ImageView myImageViewImage;
public RecyclerViewHolder(#NonNull View itemView) {
super(itemView);
myTextViewName = itemView.findViewById(R.id.launch_name);
myTextViewDate = itemView.findViewById(R.id.date);
myImageViewImage = itemView.findViewById(R.id.thumbnail);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(myListener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
myListener.onItemClick(position);
}
}
}
});
}
}
A launch object is just this:
public Launch(String name, String date, String imageUrl) {
this.name = name;
this.date = date;
this.imageUrl = imageUrl;
}
What am I doing wrong?
Recyclerview item layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:padding="8dp"
android:background="#323131">
<ImageView
android:id="#+id/thumbnail"
android:layout_width="100dp"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_margin="8dp"
android:orientation="vertical">
<TextView
android:id="#+id/launch_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Launch name"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="#android:color/white"/>
<TextView
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="Date"
android:textColor="#android:color/white"/>
</LinearLayout>
Recyclerview layout
Recyclerview layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_view"
android:background="#323131"/>
make getImage function get the index of array object and i will tell you why
String imageUrl = getImageUrl(i);
public String getImageUrl(final int index)
after getting url adding that
String url = rocket.getString("imageURL");
launchesList.get(index).imageUrl = url;
myRecyclerViewAdapter.notifyItemChanged(index);
now i tell the thread of get image get image and when finish notify adapter
it work for me
In your getImageUrl() you are returning the wrong url which is this:
String url = "https://launchlibrary.net/1.3/launch/" + launchId;
instead do this:
public String getImageUrl(){
String url = "https://launchlibrary.net/1.3/launch/" + launchId;
//add this
String imageURL = null;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("launches");
JSONObject launch = jsonArray.getJSONObject(0);
JSONObject rocket = launch.getJSONObject("rocket");
imageURL = rocket.getString("imageURL");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
myRequestQueue.add(request);
//return it here
return imageURL;
}
my friend above help u in parsing but let me know why you use two request one for parsing object and second one for get image but u should know that here you will use two thread so we will work on make them in one thread
and check if catch print any log
please send object in array to getImage function and continue to parse
String imageUrl = getImageUrl(launch );
and fix getImageUrl function
public String getImageUrl(JSONObject launch ){
JSONObject rocket = launch.getJSONObject("rocket");
String url = rocket.getString("imageURL");
return url;
}
try this if error still exist please inform me and i will try it on my code
Here is my Orderofday.java where i am getting data from URL and in String proceeding_file i get pdf link. i have shown the data present on every card but could not achieve to open a pdf link on card button clicked.
public class Orderofday extends AppCompatActivity {
private static final String TAG = Orderofday.class.getSimpleName();
private RecyclerView recyclerView;
private OrderList mAdapter;
ProgressDialog progess;
List<OrdersModel> myList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_orderofday);
progess = new ProgressDialog(Orderofday.this);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new OrderList(myList, Orderofday.this);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
getResult();
}
public void getResult() {
String url = "http://senate.gov.pk/ne/getdata/order_of_day_json.php";
//detect internet and show the data
if (isNetworkStatusAvialable(getApplicationContext())) {
progess.setMessage("Loading data....");
progess.show();
StringRequest strReq = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("response", response);
try {
JSONObject mainList = new JSONObject(response);
JSONArray result = mainList.getJSONArray("data");
if (result.length() > 0) {
for (int i = 0; i < result.length(); i++) {
mainList = result.getJSONObject(i);
OrdersModel model = new OrdersModel();
model.title_en = mainList.getString("title_en");
model.YearID = mainList.getString("YearID");
model.session_title_en = mainList.getString("session_title_en");
model.sitting_date = mainList.getString("sitting_date");
model.proceeding_file = mainList.getString("proceeding_file");
myList.add(model);
}
mAdapter.notifyDataSetChanged();
progess.dismiss();
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error: " + error.getMessage());
progess.dismiss();
}
});
Log.d("params", strReq.getUrl() + " and " + strReq.getBodyContentType() + " abd " + strReq.getBodyContentType());
// Adding String request to request queue
AppSingleton.getInstance(getApplicationContext()).addToRequestQueue(strReq, TAG);
} else {
Toast.makeText(getApplicationContext(), "Please check your Internet Connection", Toast.LENGTH_SHORT).show();
}
}
//check internet connection
public static boolean isNetworkStatusAvialable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo netInfos = connectivityManager.getActiveNetworkInfo();
if (netInfos != null) {
return netInfos.isConnected();
}
}
return false;
}
}
Here is my OrderList.java class where i am setting the text from OderModel.java
public class OrderList extends RecyclerView.Adapter<OrderList.MyViewHolder> {
List<OrdersModel> list;
Context c;
public OrderList(List<OrdersModel> list, Context c) {
this.list = list;
this.c = c;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.orders_list, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
OrdersModel movie = list.get(position);
holder.name.setText(movie.gettitle_en());
holder.type.setText(movie.getYearID());
holder.session_title.setText((movie.getsession_title_en()));
holder.sitting_date.setText(movie.getsitting_date());
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name, type , session_title , sitting_date , proceeding_file;
public MyViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
type = view.findViewById(R.id.type);
session_title = view.findViewById(R.id.session_title);
sitting_date = view.findViewById(R.id.sitting_date);
}
}
}
And here is my OrderModel.java where i made getters and setter
public class OrdersModel {
String title_en;
String YearID;
String session_title_en;
String sitting_date;
String proceeding_file;
public String gettitle_en() {
return title_en;
}
public void settitle_en(String title_en) {
this.title_en = title_en;
}
public String getYearID() {
return YearID;
}
public void setYearID(String YearID) {
this.YearID = YearID;
}
public String getsession_title_en() {
return session_title_en;
}
public void setsession_title_en(String session_title_en) {
this.session_title_en = session_title_en;
}
public String getsitting_date() {
return sitting_date;
}
public void setsitting_date(String session) {
this.sitting_date = sitting_date;
}
public String getproceeding_file() {
return proceeding_file;
}
public void setproceeding_file(String date) {
this.proceeding_file = proceeding_file;
}
String file;
}
Now i need to open a pdf against every card view clicked i got url of pdf in procedding_file (String) but couldn't get it. Kindly help me out to achieve this and here is xml.
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="#dimen/_5sdp"
android:layout_height="wrap_content"
android:padding="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/name"
android:textStyle="bold"
android:textSize="20sp"
android:layout_margin="5dp"
android:text="Title_ID"
android:textColor="#android:color/black" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/type"
android:layout_below="#id/name"
android:layout_margin="5dp"
android:textSize="15sp"
android:text="YearID"
android:textColor="#android:color/black" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/session_title"
android:layout_below="#id/type"
android:layout_margin="5dp"
android:textSize="15sp"
android:text="Session Title"
android:textColor="#android:color/black" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/sitting_date"
android:layout_below="#id/session_title"
android:layout_margin="5dp"
android:textSize="15sp"
android:text="Date "
android:textColor="#android:color/black" />
<Button
android:id="#+id/view_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/sitting_date"
android:layout_alignParentRight="true"
android:text="Click to View Pdf"
android:textColor="#000000"
android:textSize="#dimen/_10sdp">
</Button>
<com.github.barteksc.pdfviewer.PDFView
android:id="#+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
Above answer is correct. However a better solution and the rightest one is to create an interface for the clicklistenet and implement it in tour activity
Initialize viewButton in ViewHolder.
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name, type , session_title , sitting_date , proceeding_file;
public Button viewButton;
public MyViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
type = view.findViewById(R.id.type);
session_title = view.findViewById(R.id.session_title);
sitting_date = view.findViewById(R.id.sitting_date);
viewButton = view.findViewById(R.id.view_button);
}
}
Then set onClickListener on viewButton and openPdf
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
OrdersModel movie = list.get(position);
holder.name.setText(movie.gettitle_en());
holder.type.setText(movie.getYearID());
holder.session_title.setText((movie.getsession_title_en()));
holder.sitting_date.setText(movie.getsitting_date());
holder.viewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openPdf(movie.getproceeding_file())
}
});
}
Suggestion: You should move your PdfViewer in another activity and redirect user to that activity when click viewButton.
initialise view_pdf button in MyViewHolder class. like others.
parse proceeding file like others ~ movie.getproceeding_file()
under the onBindViewHolder put below snippet of code:
holder.proceeding_file.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String pdf_url = movie.getproceeding_file();
// do not forget to concate preceding url of the pdf
Webview webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(pdf_url);
}
});
i am trying to implement two recyclerview in one layout with same adapter. but only one recyclerview is showing.
MainActivity.java
public class MainActivity extends AppCompatActivity {
List<DataAdapter> ListOfdataAdapter;
String HTTP_JSON_URL = "http://example.com";
String Image_Name_JSON = "Menu_name";
String Image_URL_JSON = "Menu_image";
JsonArrayRequest RequestOfJSonArray ;
RequestQueue requestQueue ;
View view ;
int RecyclerViewItemPosition ;
RecyclerView.LayoutManager layoutManagerOfrecyclerView;
RecyclerView.Adapter recyclerViewadapter;
ArrayList<String> ImageTitleNameArrayListForClick;
long Category_ID;
String MenuAPI;
private RecyclerView secondRecyclerView;
private RecyclerView.LayoutManager secondLayoutManager;
private RecyclerView firstrecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageTitleNameArrayListForClick = new ArrayList<>();
// menu API url
Intent iGet = getIntent();
Category_ID = iGet.getLongExtra("category_id",0);
MenuAPI += Category_ID;
ListOfdataAdapter = new ArrayList<>();
firstrecyclerView = (RecyclerView) findViewById(R.id.recyclerview1);
firstrecyclerView.setHasFixedSize(true);
layoutManagerOfrecyclerView = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, true);
firstrecyclerView.setLayoutManager(layoutManagerOfrecyclerView);
firstrecyclerView.post(new Runnable() {
#Override
public void run() {
JSON_HTTP_CALL();// a method which requests remote data
}
});
secondRecyclerView = (RecyclerView) findViewById(R.id.recyclerview2);
secondRecyclerView.setHasFixedSize(true);
secondLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, true);
secondRecyclerView.setLayoutManager(secondLayoutManager);
secondRecyclerView.post(new Runnable() {
#Override
public void run() {
JSON_HTTP_CALL2();// a method which requests remote data
}
});
// Implementing Click Listener on RecyclerView.
}
public void JSON_HTTP_CALL(){
RequestOfJSonArray = new JsonArrayRequest(HTTP_JSON_URL + "/api/example.php" +"&category_id=2",
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
ParseJSonResponse(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(RequestOfJSonArray);
}
public void ParseJSonResponse(JSONArray array){
for(int i = 0; i<array.length(); i++) {
DataAdapter GetDataAdapter2 = new DataAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
GetDataAdapter2.setImageTitle2(json.getString(Image_Name_JSON));
// Adding image title name in array to display on RecyclerView click event.
ImageTitleNameArrayListForClick.add(json.getString(Image_Name_JSON));
GetDataAdapter2.setImageUrl2(HTTP_JSON_URL + "/" + json.getString(Image_URL_JSON));
} catch (JSONException e) {
e.printStackTrace();
}
ListOfdataAdapter.add(GetDataAdapter2);
}
recyclerViewadapter = new RecyclerViewAdapter(ListOfdataAdapter, getApplicationContext());
firstrecyclerView.setAdapter(recyclerViewadapter);
}
public void JSON_HTTP_CALL2(){
RequestOfJSonArray = new JsonArrayRequest(HTTP_JSON_URL + "/api/example.php" +"&category_id=2",
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
ParseJSonResponse2(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(RequestOfJSonArray);
}
public void ParseJSonResponse2(JSONArray array){
for(int i = 0; i<array.length(); i++) {
DataAdapter GetDataAdapter2 = new DataAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
GetDataAdapter2.setImageTitle2(json.getString(Image_Name_JSON));
// Adding image title name in array to display on RecyclerView click event.
ImageTitleNameArrayListForClick.add(json.getString(Image_Name_JSON));
GetDataAdapter2.setImageUrl2(HTTP_JSON_URL + "/" + json.getString(Image_URL_JSON));
} catch (JSONException e) {
e.printStackTrace();
}
ListOfdataAdapter.add(GetDataAdapter2);
}
recyclerViewadapter = new RecyclerViewAdapter(ListOfdataAdapter, getApplicationContext());
secondRecyclerView.setAdapter(recyclerViewadapter);
}
}
Adapter class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
Context context;
List<DataAdapter> dataAdapters;
ImageLoader imageLoader;
private Activity activity;
private static final int CITY_TYPE = 0;
JsonArrayRequest RequestOfJSonArray;
private static final int EVENT_TYPE = 1;
public RecyclerViewAdapter(Activity act) {
this.activity = act;
}
public RecyclerViewAdapter(List<DataAdapter> getDataAdapter, Context context){
super();
this.dataAdapters = getDataAdapter;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case CITY_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
return new ViewHolder(view);
case EVENT_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card2, parent, false);
return new ViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(ViewHolder Viewholder, int position) {
DataAdapter dataAdapterOBJ = dataAdapters.get(position);
imageLoader = ImageAdapter.getInstance(context).getImageLoader();
if (dataAdapterOBJ != null) {
switch (dataAdapterOBJ.getType()) {
case CITY_TYPE:
imageLoader.get(dataAdapterOBJ.getImageUrl2(),
ImageLoader.getImageListener(
Viewholder.VollyImageView,//Server Image
R.mipmap.ic_launcher,//Before loading server image the default showing image.
android.R.drawable.ic_dialog_alert //Error image if requested image dose not found on server.
)
);
Viewholder.VollyImageView.setImageUrl(dataAdapterOBJ.getImageUrl2(), imageLoader);
Viewholder.ImageTitleTextView.setText(dataAdapterOBJ.getImageTitle2());
break;
case EVENT_TYPE:
imageLoader.get(dataAdapterOBJ.getImageUrl2(),
ImageLoader.getImageListener(
Viewholder.VollyImageView,//Server Image
R.mipmap.ic_launcher,//Before loading server image the default showing image.
android.R.drawable.ic_dialog_alert //Error image if requested image dose not found on server.
)
);
Viewholder.VollyImageView.setImageUrl(dataAdapterOBJ.getImageUrl2(), imageLoader);
Viewholder.ImageTitleTextView.setText(dataAdapterOBJ.getImageTitle2());
break;
}
}
}
#Override
public int getItemCount() {
return dataAdapters.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView ImageTitleTextView;
public NetworkImageView VollyImageView ;
public ViewHolder(View itemView) {
super(itemView);
ImageTitleTextView = (TextView) itemView.findViewById(R.id.MenuNameTV) ;
VollyImageView = (NetworkImageView) itemView.findViewById(R.id.VolleyImageView) ;
}
}
}
main activity xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="Most Watched"/>
<!-- A RecyclerView to display horizontal list -->
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview1"
android:scrollbars="none"
android:layout_width="fill_parent"
android:layout_height="240dp"
android:paddingLeft="0dp"
android:paddingRight="15dp"
android:paddingTop="15dp"
android:paddingBottom="25dp"
android:background="#ffc000"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="All Dramas"/>
<!-- A RecyclerView to display vertical list -->
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview2"
android:layout_width="fill_parent"
android:layout_height="240dp"
android:paddingLeft="0dp"
android:paddingRight="15dp"
android:paddingTop="15dp"
android:paddingBottom="25dp"/>
i try every possible way available on internet but dont get solution.
Anything wrong i am doing?
any idea how to run two recyclerview with above code.
thankx
You can do this-
<android.support.v4.widget.NestedScrollView>
<LinearLayout>
.
.
.
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
This is used to attach 2 or more scrolling views together and one more thing you can do is to make the height of recycler view as "wrap_content".
Hope this helps.
I know that this question was asked many times before, but i'm confused why sometimes the data is loaded and sometimes data isn't loaded once i get to the end of list. Also when i go fast scrolling through the list, and the new data has been loaded, but immediately it returns me to the first item in list and remove all new loaded items from the next page from server. So that is the second problem and the third problem is that when i load items using SwipeRefreshLayout, i'm also not getting new items when i reach the end of the list.
I have implemented this in my project: https://gist.github.com/ssinss/e06f12ef66c51252563e
list.setLayoutManager(manager);
list.setEmptyView(emptyView);
list.setItemAnimator(new DefaultItemAnimator());
list.setAdapter(mAdapter);
loadJokes(1);
list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
#Override
public void onLoadMore(final int current_page) {
loadMoreJokes(current_page);
}
});
Here is the method where i'm loading more items from server:
private void loadMoreJokes(int current_page) {
StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + current_page,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject object = new JSONObject(response);
boolean error = object.getBoolean("error");
JSONArray jokes = object.getJSONArray("jokes");
if (!error) {
for (int i = 0; i < jokes.length(); i++) {
JSONObject object1 = jokes.getJSONObject(i);
Joke joke = new Joke();
joke.setId(object1.optInt("id"));
joke.setLikes(object1.optInt("likes"));
joke.setComments(object1.optInt("comments"));
joke.setJoke(object1.optString("joke"));
joke.setCreatedAt(object1.optString("created_at"));
joke.setName(object1.optString("user_name"));
joke.setImagePath(object1.optString("image_path"));
joke.setFacebookUserId(object1.optString("facebook_user_id"));
joke.setCategory(object1.optString("category"));
mJokes.add(joke);
}
menu.showMenu(true);
}
// Notify adapter that data has changed
mAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideDialog();
Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
AppController.getInstance().addToRequestQueue(request);
}
And here is the method where i'm loading first visible items when someone launch the app:
private void loadJokes(int page) {
pDialog.setMessage("Loading..");
showDialog();
StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + page,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mJokes.clear();
hideDialog();
try {
JSONObject object = new JSONObject(response);
boolean error = object.getBoolean("error");
JSONArray jokes = object.getJSONArray("jokes");
if (!error) {
for (int i = 0; i < jokes.length(); i++) {
JSONObject object1 = jokes.getJSONObject(i);
Joke joke = new Joke();
joke.setId(object1.optInt("id"));
joke.setLikes(object1.optInt("likes"));
joke.setComments(object1.optInt("comments"));
joke.setJoke(object1.optString("joke"));
joke.setCreatedAt(object1.optString("created_at"));
joke.setName(object1.optString("user_name"));
joke.setImagePath(object1.optString("image_path"));
joke.setFacebookUserId(object1.optString("facebook_user_id"));
joke.setCategory(object1.optString("category"));
mJokes.add(joke);
}
menu.showMenu(true);
}
// Notify adapter that data has changed
mAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideDialog();
menu.showMenu(true);
Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
AppController.getInstance().addToRequestQueue(request);
}
And this is onRefresh() method:
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
refreshItems();
}
}, 5000);
}
private void refreshItems() {
loadJokes(1);
mSwipeRefreshLayout.setRefreshing(false);
}
If i need to post more code, let me know. I really need to solve this problem as soon as i can. So again, the problems are the following:
When fast scrolling through the list, new items are being loaded, but immediately after that it returns me to the beginning of the list and when i go to the end of list again, load more doesn't respond.
After refreshing the list with SwipRefreshLayout, also scrolling doesn't respond at the end.
Note: The scrolling and loading new items is working only if i go slowly through the list and if i didn't swipe to refresh list.
EDIT:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_jokes, container, false);
mContext = getActivity();
mView = (CoordinatorLayout) view.findViewById(R.id.coordinatorLayout);
TextView tvEmptyText = (TextView) view.findViewById(R.id.tv_empty);
ImageView ivSignal = (ImageView) view.findViewById(R.id.iv_signal);
if (!ConnectionDetector.getInstance(getActivity()).isOnline() && mAdapter == null) {
tvEmptyText.setVisibility(View.VISIBLE);
ivSignal.setVisibility(View.VISIBLE);
showNoInternetSnackbar();
}
// INITIALIZE RECYCLER VIEW
EmptyRecyclerView list = (EmptyRecyclerView) view.findViewById(R.id.list);
mJokes = new ArrayList<>();
mAdapter = new RecyclerJokesAdapter(getActivity(), mJokes, JokesFragment.this, null);
// Progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
showDialog();
View emptyView = inflater.inflate(R.layout.layout_empty_view, container, false);
FloatingActionButton fab1 = (FloatingActionButton) view.findViewById(R.id.fab_funny);
FloatingActionButton fab2 = (FloatingActionButton) view.findViewById(R.id.fab_good_morning);
FloatingActionButton fab3 = (FloatingActionButton) view.findViewById(R.id.fab_good_night);
FloatingActionButton fab4 = (FloatingActionButton) view.findViewById(R.id.fab_all);
menu = (FloatingActionMenu) view.findViewById(R.id.menu_sort_jokes);
fab1.setOnClickListener(this);
fab2.setOnClickListener(this);
fab3.setOnClickListener(this);
fab4.setOnClickListener(this);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeResources(
R.color.refresh_progress_1,
R.color.refresh_progress_2,
R.color.refresh_progress_3);
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
list.setLayoutManager(manager);
list.setEmptyView(emptyView);
list.setItemAnimator(new DefaultItemAnimator());
list.setAdapter(mAdapter);
if (ConnectionDetector.getInstance(mContext).isOnline()) {
loadJokes(1);
} else {
showNoInternetSnackbar();
hideDialog();
}
list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
#Override
public void onLoadMore(final int current_page) {
loadMoreJokes(current_page);
}
});
return view;
}
In onCreate method initialize your adapter, recyclerView and List
List<MyObject> myList = new ArrayList<>();
recyclerViewAdapter = new RecyclerViewAdapter(context, myList)
myRecyclerView.setAdapter(recyclerViewAdapter);
Now, whenever you load data. add the data to your myList and call notifyDataSetChange on your adpater
myList.add(data);
recyclerViewAdapter.notifyDataSetChange();
Use this wrapper class
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import java.util.List;
public abstract class RecyclerWrapperAdapter<E> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
protected Context context;
protected List<E> objects;
public void setContext(Context context) {
this.context = context;
}
public void setObjects(List<E> objects) {
this.objects = objects;
notifyDataSetChanged();
}
public void add(#NonNull E object) {
objects.add(object);
notifyDataSetChanged();
}
public void add(int position, #NonNull E object) {
if (position < objects.size() && position >= 0) {
objects.add(position, object);
notifyItemChanged(position);
notifyDataSetChanged();
} else if (position >= objects.size()) {
objects.add(object);
notifyDataSetChanged();
}
}
public void set(int position, #NonNull E object) {
if (position < objects.size() && position >= 0) {
objects.set(position, object);
notifyItemChanged(position);
} else if (position >= objects.size()) {
objects.add(object);
notifyDataSetChanged();
}
}
public void remove(#NonNull E object) {
objects.remove(object);
notifyDataSetChanged();
}
public void remove(int position) {
if (position >=0 && position < objects.size()) {
objects.remove(position);
notifyDataSetChanged();
}
}
public void removeAll() {
objects.clear();
notifyDataSetChanged();
}
public E getItem(int position) {
return objects.get(position);
}
#Override
public int getItemCount() {
return objects.size();
}
}
Well I have done this way:
MainActivity .java
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener, onRecyclerViewListener {
private RecyclerView mRecyclerView;
private TextView tvEmptyView;
private LinearLayoutManager mLayoutManager;
private List<Object> studentList;
protected Handler handler;
private int count = 0;
private SwipeRefreshLayout swipeRefreshLayout;
private MyRecycleAdapter myRecycleAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swiperefresh);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeResources(R.color.blue, R.color.purple, R.color.green, R.color.orange);
tvEmptyView = (TextView) findViewById(R.id.empty_view);
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
studentList = new ArrayList<Object>();
handler = new Handler();
loadData();
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// use a linear layout manager
mRecyclerView.setLayoutManager(mLayoutManager);
myRecycleAdapter = new MyRecycleAdapter(mRecyclerView, studentList, R.layout.list_row, R.layout.progressbar_item, this);
myRecycleAdapter.setLoadMoreEnable(true);
myRecycleAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
count++;
if (count == 4) {
count = 0;
myRecycleAdapter.setLoadMoreEnable(false);
} else {
myRecycleAdapter.setLoadMoreEnable(true);
}
//add null , so the adapter will check view_type and show progress bar at bottom
studentList.add(null);
myRecycleAdapter.notifyItemInserted(studentList.size() - 1);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// remove progress item
studentList.remove(studentList.size() - 1);
myRecycleAdapter.notifyItemRemoved(studentList.size());
//add items one by one
int start = studentList.size();
int end = start + 20;
for (int i = start + 1; i <= end; i++) {
studentList.add(new Student("Student " + i, "AndroidStudent" + i + "#gmail.com"));
myRecycleAdapter.notifyItemInserted(studentList.size());
}
myRecycleAdapter.setLoaded();
//or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
}
}, 1000);
}
});
ItemViewHolderNew.setRecyclerListener(this);
mRecyclerView.setAdapter(myRecycleAdapter);
if (studentList.isEmpty()) {
mRecyclerView.setVisibility(View.GONE);
tvEmptyView.setVisibility(View.VISIBLE);
} else {
mRecyclerView.setVisibility(View.VISIBLE);
tvEmptyView.setVisibility(View.GONE);
}
}
private void loadData() {
for (int i = 1; i <= 20; i++) {
studentList.add(new Student("Student " + i, "androidstudent" + i + "#gmail.com"));
}
}
#Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
},5000);
}
#Override
public void onBindView(View view, final ItemViewHolderNew itemViewHolder) {
itemViewHolder.tvName = (TextView) view.findViewById(R.id.tvName);
itemViewHolder.tvEmailId = (TextView) view.findViewById(R.id.tvEmailId);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, Object object, ItemViewHolderNew itemViewHolder) {
Student studentObj = (Student)object;
itemViewHolder.tvName.setText(studentObj.getName());
itemViewHolder.tvEmailId.setText(studentObj.getEmailId());
itemViewHolder.student= studentObj;
}
#Override
public void setClickListener(View view, ItemViewHolderNew itemViewHolder) {
Toast.makeText(view.getContext(), "OnClick :" + itemViewHolder.student.getName() + " \n " + itemViewHolder.student.getEmailId(), Toast.LENGTH_SHORT).show();
}
public static class ItemViewHolderNew extends RecyclerView.ViewHolder{
public TextView tvName, tvEmailId;
public Student student;
private static onRecyclerViewListener mListener;
public static void setRecyclerListener(onRecyclerViewListener listener){
mListener = listener;
}
public ItemViewHolderNew(View itemView) {
super(itemView);
mListener.onBindView(itemView, this);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setClick(v);
}
});
}
private void setClick(View v) {
mListener.setClickListener(v, this);
}
}
}
Add OnLoadMoreListener.java interface
public interface OnLoadMoreListener {
void onLoadMore();
}
Add Student.java as Model class
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String emailId;
public Student(String name, String emailId) {
this.name = name;
this.emailId = emailId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="No Records Here !"
android:visibility="gone" />
</RelativeLayout>
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
android:padding="5dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="#+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:id="#+id/tvEmailId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvName"
android:layout_margin="5dp"
android:text="Email Id"
android:textColor="#android:color/black"
android:textSize="12sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvName"
android:layout_margin="5dp"
android:text="Email Id"
android:textColor="#android:color/black"
android:textSize="12sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
progressbar_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:layout_width="match_parent" android:layout_height="match_parent">
<ProgressBar
android:id="#+id/progressBar1"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content" />
</LinearLayout>
Working fine with Endless, swipe to refresh, load more RecyclerView.
Hope this would help you.
Volley RequestQueue uses a thread pool for network requests.
/** Number of network request dispatcher threads to start. */
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
Obviously, when you do fast scrolling through the list multiple requests are generated in quick succession.
There is a possibility that the responses are received asynchronously / out of sequence. Also, its possible that the "No more data" responses / error responses etc arrive before the responses with next page of data, which may lead to unexpected behaviour by your app.
Specially watch out for how this would effect your mJokes ArrayList member variable.