How to infinite scroll load more with Recycleview? - android

How to infinite scroll load more with Recycleview
how can i display result like infinite means when user scroll dynamic data automatically fetch and show. so loading time consume and application will work fine.
File Name: MainActivity.java //Main Java file that i want to show load more
package com.ejobbox.ejobbox;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ProgressBar progressBar;
private LinearLayoutManager mLayoutManager;
private RecyclerViewAdapter adapter;
private ArrayList<Model> list;
private String baseURL="http://mywebsite.com/";
public static List<WPPost> mListPost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= findViewById(R.id.recycler_view);
progressBar=findViewById(R.id.progressbar);
mLayoutManager=new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(mLayoutManager);
list=new ArrayList<Model>();
// call retrofit
getRetrofit();
adapter=new RecyclerViewAdapter(list,MainActivity.this);
recyclerView.setAdapter(adapter);
}
private void getRetrofit(){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
Call<List<WPPost>> call= service.getPostInfo();
call.enqueue(new Callback<List<WPPost>>() {
#Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.e("mainactivty","response"+ response.body());
progressBar.setVisibility(View.GONE);
for(int i=0; i<response.body().size();i++){
Log.e ("main","Title"+ response.body().get(i).getTitle().getRendered()+" "+
response.body().get(i).getId());
String tempdetails=response.body().get(i).getExcerpt().getRendered().toString();
tempdetails=tempdetails.replace("<p>","");
tempdetails=tempdetails.replace("</p>","");
String linkdetail=response.body().get(i).getLink().toString();
String date=response.body().get(i).getDate().toString();
list.add(new Model(Model.IMAGE_TYPE, response.body().get(i).getTitle().getRendered(),
tempdetails,date,
response.body().get(i).getLinks().getWpFeaturedmedia().get(0).getHref(),linkdetail) );
}
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
}
});
}
}
(This is RecyclearViewAdapter that i have define recyclear view Adapter.)
File Name: RecyclearViewAdapter.java //Recyclear View Adapter File
package com.ejobbox.ejobbox;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class RecyclerViewAdapter extends RecyclerView.Adapter{
private ArrayList<Model> dataset;
private Context mContext;
public RecyclerViewAdapter(ArrayList<Model> mlist, Context context) {
this.dataset=mlist;
this.mContext=context;
}
public static class ImageTypeViewHolder extends RecyclerView.ViewHolder{
TextView title,subtitle,link,date;
ImageView imageView;
public ImageTypeViewHolder(View itemView){
super(itemView);
this.title=(TextView)itemView.findViewById(R.id.title);
this.link=(TextView)itemView.findViewById(R.id.link);
this.subtitle=(TextView) itemView.findViewById(R.id.subtitle);
this.imageView=(ImageView) itemView.findViewById(R.id.icon);
this.date=(TextView)itemView.findViewById(R.id.date);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.postdetails,parent,false);
return new ImageTypeViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final Model object=dataset.get(position);
((ImageTypeViewHolder) holder).title.setText(object.title);
((ImageTypeViewHolder) holder).subtitle.setText(object.subtitle);
//((ImageTypeViewHolder) holder).link.setText(object.link);
((ImageTypeViewHolder) holder).date.setText((CharSequence) object.date);
((ImageTypeViewHolder) holder).title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(mContext, WPPostDetails.class);
intent.putExtra("itemPosition",position);
intent.putExtra("link",object.link.toString());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() { return dataset.size();}
}

Do not use infinite scroll it does not work as expected.
You can use this
recyclerView.addOnScrollListener(new OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (isLastItemDisplaying())
{
scrollCount=scrollCount+10;
L.v("scroll count",""+recyclerView.getAdapter().getItemCount());
loadMoreItems(scrollCount);
}
}
});
private boolean isLastItemDisplaying()
{
if (storiesList.getAdapter().getItemCount()!=0) {
int last_visible_count=manager.findFirstCompletelyVisibleItemPosition();
if (last_visible_count!=RecyclerView.NO_POSITION && last_visible_count==storiesList.getAdapter().getItemCount()-1) {
return true;
}
}
return false;
}
Inside this loadMoreItems method call your api. Make sure to send this scroll count to your server on each api call .And in sql query you have to do this
EX:
For example on first time your count is 0;
SELECT * FROM posts LIMIT 0,10
On Scroll your scrollCount value will get increased by 10 (you can use your value scroll count values will fetch next 10 rows)
SELECT * FROM posts LIMIT 10,10

You only have to add your new data to the last position of list movies and everything will work fine. For this-
Create a new List of List<Model> newList and add your updated data to it. Now add newList into list and notify to adapter. Just like below-
List<Model> newList = new ArrayList<>();
// your code..
recyclerView.addOnScrollListener(new EndlessScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
loadingMore=true;
getRetrofit();
int currentSize = adapter.getItemCount();
list.addAll(newList);
adapter.notifyItemRangeInserted(currentSize, list.size() - 2);
}
});
And here you can find the EndlessScrollListener class.
please look at my other related answers to more details-
How to load more items in a ListView using AsyncTask or any other method
Continious scrolling in recyclerview by Json request and adding new item with previous
Hope it will help.

Here is example for Simple Implementation of Endless Scrolling RecyclerView using a Simple Library compiled from the various sources.
Add this line in build.gradle
implementation 'com.hereshem.lib:awesomelib:2.0.1'
Create RecyclerView Layout in Activity with
<com.hereshem.lib.recycler.MyRecyclerView
android:id="#+id/recycler"
app:layoutManager="LinearLayoutManager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Create a ViewHolder by passing the class that supports
public static class EVHolder extends MyViewHolder<Events> {
TextView date, title, summary;
public EVHolder(View v) {
super(v);
date = v.findViewById(R.id.date);
title = v.findViewById(R.id.title);
summary = v.findViewById(R.id.summary);
}
#Override
public void bindView(Events c) {
date.setText(c.date);
title.setText(c.title);
summary.setText(c.summary);
}
}
Create Items List variable and adapters with very few lines by passing items, class and layout in the adapter
List<Events> items = new ArrayList<>();
MyRecyclerView recycler = findViewById(R.id.recycler);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, items, EVHolder.class, R.layout.row_event);
recycler.setAdapter(adapter);
ClickListener and LoadMore Listener can be added with following lines
recycler.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {
#Override
public void onItemClick(int position) {
Toast.makeText(MainActivity.this, "Recycler Item Clicked " + position, Toast.LENGTH_SHORT).show();
}
});
recycler.setOnLoadMoreListener(new MyRecyclerView.OnLoadMoreListener() {
#Override
public void onLoadMore() {
loadData();
}
});
loadData();
After the data is loaded this must be called
recycler.loadComplete();
When no LoadMore is required LoadMore layout can be hidden by calling
recycler.hideLoadMore();
More example can be found here
Hope this helps :)

Related

How to Add Multiple Indexes in a single listview String

theList.add(data.getString(0));
theList.add(data.getString(1));
theList.add(data.getString(2));
theList.add(data.getString(3));
theList.add(data.getString(4));
I want to add all these indexes as a single row
I have Tried follwing code but it didn`t worked
theList.add(data.getString(0),data.getString(1),data.getString(2),data.getString(3),data.getString(4));
This is the Full Code of my Class. What i am trying to do is take data from my sqlite database and show in list view.
By this following code i am getting values in different rows but i want them in a single row
package com.example.project;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Mitch on 2016-05-13.
*/
public class ViewListContents extends AppCompatActivity {
DBHelper myDB;
User user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewlistcontents_layout);
ListView listView = (ListView) findViewById(R.id.listView);
myDB = new DBHelper(this);
//populate an ArrayList<String> from the database and then view it
ArrayList<String> theList = new ArrayList<>();
Cursor data = myDB.viewbuses();
if(data.getCount() == 0){
Toast.makeText(this, "There are no contents in this list!",Toast.LENGTH_LONG).show();
}else{
while(data.moveToNext()) {
theList.add(data.getString(0));
theList.add(data.getString(1));
theList.add(data.getString(2));
theList.add(data.getString(3));
theList.add(data.getString(4));
theList.add("");
ListAdapter listAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,theList);
listView.setAdapter(listAdapter);
}
}
}
}
Thanks in Advance
This is How I Resolved It
First of All Thanks to Mr. Zain He Helped me to get it done.
I Concatenated Strings and it worked.
I wanted to Give space Between Values so this is how I did it.
theList.add(data.getString(0)+" "+data.getString(1)+" "
+data.getString(2)+" " +data.getString(3)+" "+data.getString(4));
A Good Practice is to add .Concat() instead of "+"
Thank You!
I recommend using RecyclerView instead because it provides far more functionality than ListView. It also leads to better performance. You will have to extend RecyclerView.Adapter and RecyclerView.ViewHolder as shown below.
MyAdapter is similar to ArrayAdapter. It connects the RecyclerView to our data.
MyDataViewHolder stores all the views for a single item in the list. In our case that is a single TextView, but it could be more.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyDataViewHolder> {
private List<String> mList;
public MyAdapter(List<String> list){
this.mList = list;
}
protected static class MyDataViewHolder extends RecyclerView.ViewHolder{
protected TextView viewData;
public MyDataViewHolder(View itemView) {
super(itemView);
viewData = (TextView) itemView.findViewById(R.id.data);
}
}
}
You will also have to implement the following methods inside MyAdapter.
onCreateViewHolder creates a MyDataViewHolder from xml.
onBindViewHolder populates the MyDataViewHolder using our data.
returns the number of elements shown.
#Override
public MyDataViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.my_data, viewGroup, false);
return new MyDataViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyDataViewHolder viewHolder, int i) {
String string = mList.get(i);
viewHolder.viewData.setText(person.getLastName());
}
#Override
public int getItemCount() {
return mList.size();
}
Now use this inside your onCreate function.
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mRecyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), numberOfColumns));
mAdapter = new MyAdapter(mList);
mRecyclerView.setAdapter(mAdapter);

how can i apply limit to recyclerview?

i want apply limit to recyclerview and only show 5 result in it and in the end of the list show a button for go to another place?!
my code in below;
adapter codes:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.Holder> {
ArrayList<Products> ProductsList;
Context context;
public ProductAdapter(ArrayList<Products> productsList, Context context) {
ProductsList = productsList;
this.context = context;
}
#NonNull
#Override
public Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.row_layout_horizental, parent, false);
return new Holder(v);
}
#Override
public void onBindViewHolder(#NonNull Holder holder, int position) {
Products products = ProductsList.get(position);
holder.txtName.setText(products.getName());
holder.txtPrice.setText(products.getPrice());
Picasso.get().load(Config.ip_value + "/images/" + products.getPhoto()).into(holder.imgV);
}
#Override
public int getItemCount() {
return ProductsList.size();
}
public class Holder extends RecyclerView.ViewHolder {
TextView txtName;
TextView txtPrice;
ImageView imgV;
public Holder(#NonNull View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.rowTxtProductName);
txtPrice = itemView.findViewById(R.id.rowTxtPrice);
imgV = itemView.findViewById(R.id.rowImgProduct);
}
}
}
i have some codes in main fragment but i dont think its necessary to put in this place but if you want to see them comment and i will put all in update text
thanks
You can either slice the list to contain only 5 items before passing it to RecyclerView or just change getItemCount method in Adapter to return 5
#Override
public int getItemCount() {
return ProductsList.size() > 5 ? 5 : ProductsList.size();
}
You can set limit as by using getItemCount() as
#Override
public int getItemCount() {
return 5;
}
by another place if u mean to other activity or fragment, then place
the button at the end of your recyclerview layout in your xml file.
for e.g : if using RelativeLayout,
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="#+id/recyclerview"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Next"
android:layout_alignParentBottom="true"
android:layout_below="#+id/recyclerview"
android:id="#+id/btn_next"/>
</RelativeLayout>
then on button click you can call the intent or similar to go to your page
You can set limit query in your ProductsList API.
if you are using retrofit2
you can define limit parametr in your API interface, if that option has in your backend server,
#GET("products")
Call<Products> getProducts(#Query("limit") int limit);
and define method in your activity class where you pass setAdapter, like below
public void getProducts(int limit){
Call<Products> call = yourAPI.getProducts(limit);
call.enqueue(new Callback<Products>() {
#Override
public void onResponse(Call<Products> call, Response<Products> response) {
if (response.isSuccessful() && response.body() != null) {
ArrayList<Products> products = response.body();
if (products == null) products = new ArrayList<>();
productsAdapter.setData(products); // setData needs to be defined in your adapter
} else {
Toast.makeText(yourActivity.this, "Server Error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Products> call, Throwable t) {
if(t.getMessage() != null) Log.e("ErrorTag", t.getMessage());
Toast.makeText(yourActivity.this, "Server Error", Toast.LENGTH_SHORT).show();
}
});
Don't forget to define new method called setData,
public void setData(ArrayList<Products> productsList) {
this.ProductsList.addAll(productsList);
notifyDataSetChanged();
};
And to get other 5 products I don't advise you to create next or prev button,
better add code below in your onBindViewHolder method of your adapter to make load another 5 more products when user scrolls to the last item,
if (position == (ProductsList.size() - 1)){
if (context instanceof YourActivity){
YourActivity activity = (YourActivity) context;
activity.getProducts(ProductsList.size());
}
}

onitemclick listener doesnt work from Dialog

I'm invoking an android Dialog from button click defined inside oncreate. The dialog appears with the set recyclerview. But clicking on recyclerview items doesnt work atall. Actually .setonclicklistener is defined. Pls find the code below.
public void openreview() {
rv_review=(RecyclerView)slctssn.findViewById(R.id.rv_test);
adapter_review = new review_adapter(this, questions);
rv_review.setLayoutManager(new GridLayoutManager(this,10));
rv_review.setAdapter(adapter_review);
adapter_review.setOnItemClickListener(onClickedReview);
slctssn.show();
}
Code for clicklistener definition :
public View.OnClickListener onClickedReview = new View.OnClickListener() {
#Override
public void onClick(View view) {
RecyclerView.ViewHolder viewHolder = (RecyclerView.ViewHolder) view.getTag();
int revposition = viewHolder.getAdapterPosition();
mcqoptions one = new mcqoptions();
mcqoptions two = new mcqoptions();
mcqoptions three = new mcqoptions();
mcqoptions four = new mcqoptions();
one.setOption(qSet[revposition][1].toString());
two.setOption(qSet[revposition][2].toString());
three.setOption(qSet[revposition][3].toString());
four.setOption(qSet[revposition][4].toString());
nowStory.clear();
nowStory.add(one);
nowStory.add(two);
nowStory.add(three);
nowStory.add(four);
adapter.notifyDataSetChanged();
questionTxt=(TextView)findViewById(R.id.txtvQ);
questionTxt.setText(qSet[qsetCntr][0].toString());
}
};
Pls help to fix this.
here is my adapter code :
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class review_adapter extends RecyclerView.Adapter<review_adapter.rvViewHolder>{
private List<review_objects> questions;
private Context contxt;
/*** for item click listener purpose as collected from GIT HUB RohitSurwase /
RvClickListenerExample ***/
private View.OnClickListener adOnItemClickListener;
public review_adapter(Context c, List<review_objects> review_objects){
this.contxt= c;
this.questions=review_objects;
}
#NonNull
#Override
public rvViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType){
LayoutInflater inflater = LayoutInflater.from(contxt);
View view = inflater.inflate(R.layout.reviews_layout,parent,false);
return new rvViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull rvViewHolder holder, int position){
String postmtr= questions.get(position).getSerial();
holder.qstnum.setText(postmtr);
}
#Override
public int getItemCount() {
return questions.size();
}
public void setOnItemClickListener(View.OnClickListener itemClickListener) {
adOnItemClickListener = itemClickListener;
}
public class rvViewHolder extends RecyclerView.ViewHolder{
TextView qstnum;
public rvViewHolder(#NonNull View itemView) {
super(itemView);
qstnum = itemView.findViewById(R.id.reviewqnum);
itemView.setTag(this);
itemView.setOnClickListener(adOnItemClickListener);
}
}
}
I could fix it. There were two problems.
questionTxt.setText(qSet[qsetCntr][0].toString()); it was to be like :
questionTxt.setText(qSet[revposition][0].toString());
also one textview element in two places were sharing name. I corrected that also.
So the problem is over.
Thank you.

How to set OnclickListener for the dynamically added items in recyclerview?

In my application I'm using a recycler view to show some data and for each item in recyclerview I'm adding a list of checked text view. These checked textviews are added according to the size of list provided and it works fine. Now I want to add the click listener for those items to know if they are checked or not?
When items are checked those checked items should be taken to another activity. But now the click listener is added directly in recycler view which won't access me to do out of box code. So I'm looking for how to add a click listener and access it in another activity.
My Recyclerview code:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.allio.customer.R;
import com.allio.customer.models.Types_Item;
import com.bumptech.glide.Glide;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.github.florent37.expansionpanel.ExpansionLayout;
import com.github.florent37.expansionpanel.viewgroup.ExpansionLayoutCollection;
public class Types_adapter extends FirestoreRecyclerAdapter<Types_Item, Types_adapter.RecyclerHolder> {
private final ExpansionLayoutCollection expansionsCollection = new ExpansionLayoutCollection();
Context context;
public Types_adapter(#NonNull FirestoreRecyclerOptions<Types_Item> options, Context context) {
super(options);
expansionsCollection.openOnlyOne(true);
this.context = context;
}
#Override
protected void onBindViewHolder(#NonNull RecyclerHolder holder, int position, #NonNull Types_Item model) {
expansionsCollection.add(holder.getExpansionLayout());
holder.textView.setText(model.getName());
Glide.with(holder.imageView.getContext())
.load(model.getImageURL())
.into(holder.imageView);
CheckedTextView[] textView = new CheckedTextView[model.getProblems().size()];
holder.problems.removeAllViews();
for (int i = 0; i < model.getProblems().size(); i++){
textView[i] = new CheckedTextView(context);
textView[i].setText(model.getProblems().get(i));
textView[i].setPadding(10,10,10,10);
textView[i].setTextSize(15);
int finalI = i;
textView[i].setOnClickListener(v -> {
if (textView[finalI].isChecked()){
textView[finalI].setChecked(false);
textView[finalI].setCheckMarkDrawable(0);
}else {
textView[finalI].setChecked(true);
textView[finalI].setCheckMarkDrawable(R.drawable.checked);
}
});
holder.problems.addView(textView[i]);
}
}
#NonNull
#Override
public RecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return RecyclerHolder.buildFor(parent);
}
public final static class RecyclerHolder extends RecyclerView.ViewHolder {
private static final int LAYOUT = R.layout.item_types;
ExpansionLayout expansionLayout;
TextView textView;
ImageView imageView;
LinearLayout problems;
public static RecyclerHolder buildFor(ViewGroup viewGroup){
return new RecyclerHolder(LayoutInflater.from(viewGroup.getContext()).inflate(LAYOUT, viewGroup, false));
}
public RecyclerHolder(View itemView) {
super(itemView);
expansionLayout = itemView.findViewById(R.id.expansionLayout);
textView = itemView.findViewById(R.id.type_name);
imageView = itemView.findViewById(R.id.type_image);
problems = itemView.findViewById(R.id.problems_list);
}
public ExpansionLayout getExpansionLayout() {
return expansionLayout;
}
}
}
make an interface class and bind this interface into constructor of adapter class.
public interface CustomDialogListener {
void onItemClicked(CheckedTextView checkedTextView);
}
this is for adapter class
private CustomDialogListener mViewClickListener;
public ProductsAdapter(Context context,boolean status) {
this.context = context;
this.status = status;
this.mViewClickListener = (CustomDialogListener) context;
}
and assign interface class method on your required action like onClick on any view.
textView[i].setOnClickListener(v -> {
if (textView[finalI].isChecked()){
textView[finalI].setChecked(false);
textView[finalI].setCheckMarkDrawable(0);
}else {
textView[finalI].setChecked(true);
textView[finalI].setCheckMarkDrawable(R.drawable.checked);
}
listener.onItemClicked(textView);
});
add implementation of interface in parent activity class and override the interface method.
public class ParentActivity extends AppCompatActivity implements
YourAdapter.CustomDialogListener {
#Override
public void onItemClicked(CheckedTextView checkedTextView) {
//Log.d("Item clicked", checkedTextView.isChecked()+"");
}
}
thats the way to track event of recyclerView.
hope i made myself clear.

Android: Implementing mopub native ads in recyclerview gives incorrect item positions and IndexOutOfBoundsException

In my android app I'm trying to implement mopub native ads. Before using these native ads my app was functioning correctly as expected. Now it gives outofbound exceptions and incorrect items when list item is clicked. I'm using recyclerview and using infinite scrolling, it gets item from my api and displays item correctly, but when clicking on item it gives incorrect item.
Here is my recyclerview adapter below.
package com.example.adapters;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.MyApplication;
import com.example.R;
import com.example.events.ErrorLoadingFeed;
import com.example.events.FeedLoaded;
import com.example.events.LoadMoreFeed;
import com.example.model.Post;
import com.example.model.Pagination;
import com.example.ui.InfoActivity;
import com.example.utils.MyAppConstants;
import com.google.gson.Gson;
import com.squareup.picasso.Picasso;
import java.util.List;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Header;
import retrofit.client.Response;
/**
* Created by starwar on 08/09/15.
*/
public class PostRecycleAdapter extends RecyclerView.Adapter<com.example.adapters.PostRecycleAdapter.PostViewHolder> implements Callback<List<Post>> {
private Context mContext;
private List<Post> mPosts;
// Allows to remember the last item shown on screen
private int lastPosition = -1;
// Pagination
private Pagination mPagination;
public PostRecycleAdapter(Context context, List<Post> posts) {
mContext = context;
mPosts = posts;
}
#Override
public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
PostViewHolder viewHolder = new PostViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(PostViewHolder holder, int position) {
holder.bindPost(mPosts.get(position));
// Here you apply the animation when the view is bound
setAnimation(holder.mPostName, position);
//check for last item
if ((position >= getItemCount() - 1)) {
// Loading next set of list items on scroll
if (mPagination != null && !mPagination.getOutOfRange() && mPagination.getNextPage() != null){
MyApplication.bus.post(new LoadMoreFeed(mPagination));
}
}
}
#Override
public int getItemCount() {
return mPosts == null ? 0 : mPosts.size();
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position)
{
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition)
{
Animation animation = AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
public class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mPostName;
public ImageView mAnchorImage;
public PostViewHolder(View itemView) {
super(itemView);
mPostName = (TextView) itemView.findViewById(R.id.postName);
mAnchorImage = (ImageView) itemView.findViewById(R.id.anchorImage);
itemView.setOnClickListener(this);
}
public void bindPost(Post post) {
mPostName.setText(post.getName());
String postImage = post.getPostImage();
Picasso.with(mContext)
.load(postImage)
.placeholder(R.drawable.avatar_empty)
.into(mAnchorImage);
}
#Override
public void onClick(View view) {
int position = getAdapterPosition(); // gets item position
Post post = mPosts.get(position);
int postId = post.getId();
String postName = post.getName();
Intent intent = new Intent(mContext, InfoActivity.class);
intent.putExtra(MyAppConstants.POST_ID, postId);
intent.putExtra(MyAppConstants.POST_NAME, postName);
mContext.startActivity(intent);
}
}
#Override
public void success(List<Post> posts, Response response) {
if (mPosts == null) {
mPosts = posts;
} else {
mPosts.addAll(posts);
}
notifyDataSetChanged();
List<Header> headerList = response.getHeaders();
for(Header header : headerList) {
if ("X-Pagination".equals(header.getName())) {
Gson gson = new Gson();
mPagination = gson.fromJson(header.getValue(), Pagination.class);
}
}
MyApplication.bus.post(new FeedLoaded(mPagination));
}
#Override
public void failure(RetrofitError error) {
Log.d("Call", " : Failed => " + error);
MyApplication.bus.post(new ErrorLoadingFeed(error));
}
public void clearData() {
if (mPosts != null) {
mPosts.clear();
notifyDataSetChanged();
}
}
public List<Post> getPosts() {
return mPosts;
}
}
And I'm using guide given here to show ads
https://dev.twitter.com/mopub/native/native-android-sdk-integration
Please help. what I can/should do to resolve this.
Thanks in advance.
I know this is an old question, but I was looking for the answer for a couple of hours. Probably I'll save someone's time with this solution.
If you will look carefully documentation here: https://github.com/mopub/mopub-android-sdk/wiki/Native-Ads-with-Recycler-View you will find this:
If you register any data observers on your original Adapter, you should instead register them on the MoPubRecyclerAdapter so they will receive messages with the adjusted position of content items. If you do not do this, the positions you receive for insertion and removal messages may be inaccurate. Be sure to check isAd(position) and use MoPubRecyclerAdapter#getOriginalPosition if you need the position of the item in your local adapter.
So, to get real position, it is necessary to use MoPubRecyclerAdapter.getOriginalPosition(position_in_your_adapter) method.

Categories

Resources