Facebook Native Ads in RycyclerView android - java

I found similar issue Facebook Native ads in recycler view android , but had some problems with integration with Custom Ad.
For the first I tried to describe NativeAdsManager :
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
manager = new NativeAdsManager(getActivity(), "892769720837476_892772047503910", 5);
manager.setListener(this);
manager.loadAds();
nativeAd = new NativeAd(getActivity(), "892769720837476_892772047503910");
nativeAd.setAdListener(this);
nativeAd.loadAd();
...
}
Then I included Native ad as a parameter in RecyclerAdapter constructor:
adapter = new RecyclerAdapter(foodDataList, getActivity(), nativeAd);
In this Class I also implement AdListener and NativeAdsManager.Listener methods:
#Override
public void onError(Ad ad, AdError adError) {
}
#Override
public void onAdLoaded(Ad ad) {
}
#Override
public void onAdClicked(Ad ad) {
}
#Override
public void onAdsLoaded() {
System.out.println("Loaded in fragment");
nativeAd = manager.nextNativeAd();
nativeAd.setAdListener(this);
adapter.notifyDataSetChanged();
}
#Override
public void onAdError(AdError adError) {
}
After that in RecyclerAdapter class :
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (holder.getItemViewType()) {
...
case 2:
AdditionalHolder new_holder = (AdditionalHolder) holder;
adView = NativeAdView.render(context, nativeAd, NativeAdView.Type.HEIGHT_100);
new_holder.templateContainer.addView(adView);
return;
...
public class AdditionalHolder extends RecyclerView.ViewHolder {
protected LinearLayout templateContainer;
public AdditionalHolder(View view) {
super(view);
templateContainer = (LinearLayout) view.findViewById(R.id.ad_test2);
}
}
After all of that my Fragment with RecyclerView becomes very "luggy" and every time I can see more and more ads items (1 - from the beginning, 2 - after 10 items, 3 - after next 10 and so on).
It's my first time of using multiple RecyclerView holders, and find this issue difficult.
Provide you with gist of 2 Classes
https://gist.github.com/burnix/6af8196ee8acf5c8f94e - RecyclerAdapter.class
https://gist.github.com/burnix/53dc2ed7446969b78f07 - FragmentList.class
Help me please to solve lugs problem and to place AudienceNetwork as it needs to be.
Thanks in advance!

After several hours of headache I solved my problem.
I needed to change the constructor of RecyclerView:
public RecyclerAdapter(List<FoodData> food, Context context, NativeAd nativeAd, NativeAdsManager manager) {
this.foodDataList = food;
this.context = context;
this.nativeAd = nativeAd;
this.manager = manager;
}
And implement the behavior of Native Ads in onBindViewHolder:
AdditionalHolder new_holder = (AdditionalHolder) holder;
try {
new_holder.templateContainer.removeViewInLayout(adView);
} catch (Exception e) {
e.printStackTrace();
}
nativeAd = manager.nextNativeAd();
try {
adView = NativeAdView.render(context, nativeAd, NativeAdView.Type.HEIGHT_300);
} catch (NullPointerException e) {
e.printStackTrace();
}
new_holder.templateContainer.addView(adView);
new_holder.blank_holder.setVisibility(View.GONE);
But it hasn't solved my problem entirely (micro-lags while scrolling), but still it could be useful for someone, I hoped.

Youur adapter==>
import android.app.Activity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.romantic.pictures.hd.love.wallpaper.download.R;
import com.romantic.pictures.hd.love.wallpaper.download.activity.ROMANTIC_LOVE_WALLPAPER;
import com.romantic.pictures.hd.love.wallpaper.download.model.ImageStorage;
import java.util.ArrayList;
/**
* Created by abc on 4/11/2018.
*/
public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public final int CONTENT_TYPE = 0;
public final int AD_TYPE = 1;
private OnItemClickListener mOnItemClickListener;
Activity context;
ArrayList<ImageStorage> catagorilist;
public ImageAdapter(Activity context, ArrayList<ImageStorage> catagorilist, OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
this.context = context;
this.catagorilist = catagorilist;
}
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
#Override
public int getItemViewType(int position) {
Log.e("TAG", "getItemViewType position : " + position);
Log.e("TAG", "getItemViewType position% : " + position % 5);
if (position % 7 == 0)
return AD_TYPE;
return CONTENT_TYPE;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case CONTENT_TYPE:
Log.e("TAG", "content type : ");
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout2, parent, false);
return new MyHolder(view);
case AD_TYPE:
Log.e("TAG", "ad type : ");
View nativeView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_nativead, parent, false);
return new NativeAd(nativeView);
default:
Log.e("TAG", "default : ");
LayoutInflater inflater1 = LayoutInflater.from(parent.getContext());
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout2, parent, false);
return new MyHolder(v);
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
holder.setIsRecyclable(false);
int viewType = getItemViewType(position);
ImageStorage listitem = catagorilist.get(position);
switch (viewType) {
case CONTENT_TYPE:
Log.e("TAG", "bind CONTENT_TYPE : ");
final MyHolder menuItemHolder = (MyHolder) holder;
// holder.imagview.setText(listitem.getId());
/*holder.cat_name.setText(listitem.getName());*/
Glide.with(context).load("http://learntodraw.in/ImageApp/new_" + listitem.getCat_imagem()).listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
menuItemHolder.progressBar.setVisibility(View.GONE);
return false;
}
}).into(menuItemHolder.imagview);
Log.e("TAG", "onBindViewHolder: " + "http://learntodraw.in/ImageApp/new_" + listitem.getCat_imagem());
Log.e("TAG", "onBindViewHolder: " + position);
menuItemHolder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v, position);
}
});
break;
case AD_TYPE:
Log.e("TAG", "bind AD_TYPE : ");
final NativeAd nativeHolder = (NativeAd) holder;
ROMANTIC_LOVE_WALLPAPER.showNativeVidAd(context, nativeHolder.container);
nativeHolder.container_height.post(new Runnable() {
public void run() {
// int height = nativeHolder.container_height.getHeight();
ViewGroup.LayoutParams params = nativeHolder.container.getLayoutParams();
// params.height = height;
params.height = LinearLayout.LayoutParams.WRAP_CONTENT;
nativeHolder.container.setLayoutParams(params);
// nativeHolder.linearlayout_title.setVisibility(View.GONE);
}
});
break;
}
}
#Override
public int getItemCount() {
return catagorilist.size();
}
public class MyHolder extends RecyclerView.ViewHolder {
public ImageView imagview;
public LinearLayout mainLayout;
public CardView cardview;
public ProgressBar progressBar;
public MyHolder(View itemView) {
super(itemView);
imagview = (ImageView) itemView.findViewById(R.id.imagview);
mainLayout = (LinearLayout) itemView.findViewById(R.id.mainLayout);
progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar);
cardview = (CardView) itemView.findViewById(R.id.cardview);
}
}
public static class NativeAd extends RecyclerView.ViewHolder {
LinearLayout container;
LinearLayout container_height;
// LinearLayout linearlayout_title;
public NativeAd(View view) {
super(view);
container = view.findViewById(R.id.native_ad_container);
container_height = view.findViewById(R.id.container_height);
/* linearlayout_title = view.findViewById(R.id.linearlayout_title);*/
}
}
}
public static void showNativeVidAd(final Activity context, final LinearLayout nativeContainer) {
final NativeAd nativeAd = new NativeAd(context, context.getString(R.string.fb_test_ad_img) + context.getString(R.string.native_ads3));
// final NativeAd nativeAd = new NativeAd(context, context.getString(R.string.facebook_native_ad_unit_id));
nativeAd.setAdListener(new com.facebook.ads.AdListener() {
#Override
public void onError(Ad ad, AdError error) {
// Ad error callback
Log.e("TAG", "facebook native error : " + error.getErrorMessage());
nativeContainer.setVisibility(View.GONE);
}
#Override
public void onAdLoaded(Ad ad) {
// Ad loaded callback
Log.e("TAG", "facebook native onAdLoaded : ");
if (nativeAd != null) {
nativeAd.unregisterView();
}
try {
LinearLayout nativeAdContainer = nativeContainer;
nativeAdContainer.setVisibility(View.VISIBLE);
// Add the Ad view into the ad container.
nativeAdContainer = (LinearLayout) context.findViewById(R.id.native_ad_container);
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the Ad view. The layout referenced should be the one you created in the last step.
RelativeLayout adView = (RelativeLayout) inflater.inflate(R.layout.custom_nativead, nativeAdContainer, false);
nativeAdContainer.removeAllViews();
nativeAdContainer.addView(adView);
// Create native UI using the ad metadata.
MediaView nativeAdMedia = (MediaView) adView.findViewById(R.id.native_ad_media);
/* //TextView nativeAdSocialContext = (TextView) adView.findViewById(R.id.native_ad_social_context);
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "ProximaNova-Semibold.otf");
nativeAdSocialContext.setTypeface(typeface);*/
// TextView nativeAdCallToAction = (TextView) adView.findViewById(R.id.native_ad_call_to_action);
// Set the Text.
// nativeAdSocialContext.setText(nativeAd.getAdSocialContext());
// nativeAdCallToAction.setText(nativeAd.getAdCallToAction());
// Download and display the ad icon.
// NativeAd.Image adIcon = nativeAd.getAdIcon();
// Download and display the cover image.
nativeAdMedia.setNativeAd(nativeAd);
// Add the AdChoices icon
LinearLayout adChoicesContainer = (LinearLayout) adView.findViewById(R.id.ad_choices_container);
AdChoicesView adChoicesView = new AdChoicesView(context, nativeAd, true);
adChoicesContainer.addView(adChoicesView);
// Register the Title and CTA button to listen for clicks.
List<View> clickableViews = new ArrayList<>();
// clickableViews.add(nativeAdCallToAction);
clickableViews.add(nativeAdMedia);
clickableViews.add(adChoicesContainer);
nativeAd.registerViewForInteraction(nativeAdContainer, clickableViews);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onAdClicked(Ad ad) {
// Ad clicked callback
}
#Override
public void onLoggingImpression(Ad ad) {
// Ad impression logged callback
Log.e("TAG", "facebook native onLoggingImpression");
}
});
// Request an ad
nativeAd.loadAd(NativeAd.MediaCacheFlag.ALL);
}

Related

How to load AdMobs inside RecycleView after every 5th row?

I am trying to implement AdMobs to load ads, every 5th row but i am having a difficult time, as you can see from my screenshot ads are being loaded successfully but they're being loaded after every row. Can someone help me accomplish this? I already tried reading through post on stack overflow but none seems to help. Thank you in advance. image screenshot
Fragment
public class SectorPerformanceFragment extends Fragment {
private RecyclerView newsFeedRecycleView;
private SectorPerformanceAdapter mostActiveAdapter;
private RecyclerViewAdopter recyclerViewAdopter;
public static final int ITEMS_PER_AD = 9;
private RecyclerView.LayoutManager layoutManager;
private RequestQueue requestQueue;
private JSONObject stockDetails;
public static ArrayList<SectorPerformanceModel> mostActiveArrayList;
private RequestQueue requestQueues;
private ImageView backImage;
private View rootView;
private ProgressBar loadingProgressBar;
private TextView sectorNameTv;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.recycle_view_list_ui, container, false);
sectorNameTv = rootView.findViewById(R.id.sectorNameTv);
sectorNameTv.setText("Sector Performance");
loadingProgressBar = rootView.findViewById(R.id.loadingProgressBar);
backImage = rootView.findViewById(R.id.backImageView);
backImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().popBackStack();
//
// Fragment generalMarketFragment = new BrowseFragment();
// FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
// FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// fragmentTransaction.replace(R.id.fragment_container, generalMarketFragment);
// fragmentTransaction.addToBackStack(null);
// fragmentTransaction.commit();
}
});
requestQueues = Volley.newRequestQueue(getActivity());
findViewById();
mostActiveArrayList = new ArrayList<>();
initRecycleView();
retreiveBundleInformation();
return rootView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void findViewById() {
newsFeedRecycleView = rootView.findViewById(R.id.recylcle_view_list);
}
//set up RecycleVIew/listener to detect taps layout manager tels recycle view how to display the list.. without it, nothing shows up
public void initRecycleView() {
layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
newsFeedRecycleView.setHasFixedSize(true);
newsFeedRecycleView.setLayoutManager(layoutManager);
//mostActiveAdapter = new SectorPerformanceAdapter(getContext(), mostActiveArrayList);
// recyclerViewAdopter = new RecyclerViewAdopter(getContext(),mostActiveArrayList);
//
// //newsFeedRecycleView.setAdapter(mostActiveAdapter);
// newsFeedRecycleView.setAdapter(recyclerViewAdopter);
}
//download news data stocknewsapi..
private void downloadStockList(String api) {
// Initialize a new JsonArrayRequest instance
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
api,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
// Do something with response
//mTextView.setText(response.toString());
loadingProgressBar.setVisibility(View.INVISIBLE);
//Log.i("jsonResponse", response.toString());
// Process the JSON
// Loop through the array elements
for (int i = 0; i < response.length(); i++) {
// Get current json object
try {
stockDetails = response.getJSONObject(i);
Log.i("stockDetails", stockDetails.toString());
SectorPerformanceModel sectorPerformanceModel2 = new SectorPerformanceModel(stockDetails.getString("sector"),stockDetails.getString("changesPercentage"),1);
mostActiveArrayList.add((sectorPerformanceModel2));
SectorPerformanceModel sectorPerformanceModel3 = new SectorPerformanceModel(stockDetails.getString("sector"),stockDetails.getString("changesPercentage"),2);
mostActiveArrayList.add(mostActiveArrayList.size(),sectorPerformanceModel3);
recyclerViewAdopter = new RecyclerViewAdopter(getContext(),mostActiveArrayList);
//newsFeedRecycleView.setAdapter(mostActiveAdapter);
newsFeedRecycleView.setAdapter(recyclerViewAdopter);
//recyclerViewAdopter.notifyDataSetChanged();
// mostActiveArrayList.add(sectorPerformanceModel);
// mostActiveAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("error", error.toString());
}
}
);
// Add JsonArrayRequest to the RequestQueue
requestQueues.add(jsonArrayRequest);
}
public void retreiveBundleInformation() {
downloadStockList("APIKEY");
}
}
Adapter
[public class RecyclerViewAdopter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Context mContext;
private List<SectorPerformanceModel> mList;
public RecyclerViewAdopter(Context mContext, List<SectorPerformanceModel> mList) {
this.mList = mList;
this.mContext = mContext;
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name;
private TextView newsTitle, sourceName, epsEstiatmate;
private CircleImageView newsThumbImage;
public MyViewHolder(View view) {
super(view);
epsEstiatmate = itemView.findViewById(R.id.formTypeTv);
newsTitle = itemView.findViewById(R.id.tickerTv);
sourceName = itemView.findViewById(R.id.dateTv);
newsThumbImage= itemView.findViewById(R.id.defaultImageColor);
newsThumbImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("tapped","TAPPED");
}
});
}
}
public static class ViewHolderAdMob extends RecyclerView.ViewHolder {
public AdView mAdView;
public ViewHolderAdMob(View view) {
super(view);
mAdView = (AdView) view.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mAdView.loadAd(adRequest);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch(viewType){
case 1:{
View v = inflater.inflate(R.layout.trending_stock_row, parent, false);
viewHolder = new MyViewHolder(v);
break;
}
case 2:{
View v = inflater.inflate(R.layout.ads_row, parent, false);
viewHolder = new ViewHolderAdMob(v);
break;
}
}
return viewHolder;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
SectorPerformanceModel model= mList.get(holder.getAdapterPosition());
switch(holder.getItemViewType()){
case 1:{
MyViewHolder viewHolder = (MyViewHolder) holder;
Random r = new Random();
int red = r.nextInt(255 - 0 + 1) + 0;
int green = r.nextInt(255 - 0 + 1) + 0;
int blue = r.nextInt(255 - 0 + 1) + 0;
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.OVAL);
draw.setColor(Color.rgb(red, green, blue));
viewHolder.newsThumbImage.setBackground(draw);
viewHolder.newsTitle.setText(model.getSector());
viewHolder.sourceName.setText(model.getChangesPercentage());
break;
}
case 2:{
break;
}
}
}
#Override
public int getItemViewType(int position) {
return mList.get(position).getViewType();
}
#Override
public int getItemCount() {
return mList.size();
}
}][1]
It looks like you are adding 2 items to your adapter's data source for each element in your API response: one element has viewType 1 and the other viewType 2:
SectorPerformanceModel sectorPerformanceModel2 = new SectorPerformanceModel(stockDetails.getString("sector"),stockDetails.getString("changesPercentage"),1);
mostActiveArrayList.add((sectorPerformanceModel2));
SectorPerformanceModel sectorPerformanceModel3 = new SectorPerformanceModel(stockDetails.getString("sector"),stockDetails.getString("changesPercentage"),2);
mostActiveArrayList.add(mostActiveArrayList.size(),sectorPerformanceModel3);
Your adapter is rendering items with viewType 2 as ad rows, so if you want to display an ad row every 5 rows you'll need to update the downloadStockList method to execute this
SectorPerformanceModel sectorPerformanceModel3 = new SectorPerformanceModel(stockDetails.getString("sector"),stockDetails.getString("changesPercentage"),2);
mostActiveArrayList.add(mostActiveArrayList.size(),sectorPerformanceModel3);
only after having added 4 items with viewType 1.

my adapter of recycler view returning null

I am trying to use a RecyclerView with an adapter to call a specific
person. In the adapter I am using a call button and taking a reference from
PlaceCallActivity. The problem is that PlaceCallActivity is
using the above values which I can't access from the adapter. Thanks in advance for your help.
My PlaceCallActivity:
package techheromanish.example.com.videochatapp;
import com.sinch.android.rtc.calling.Call;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class PlaceCallActivity extends BaseActivity {
private Button mCallButton;
private EditText mCallName;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainn);
//initializing UI elements
//mCallName = (EditText) findViewById(R.id.callName);
mCallButton = (Button) findViewById(R.id.callButton);
//mCallButton.setEnabled(false);
//mCallButton.setOnClickListener(buttonClickListener);
Button stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setOnClickListener(buttonClickListener);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
listItems = new ArrayList<>();
// loadRecyclerViewData();
ListItem listItem = new ListItem(
R.drawable.user,
"Jawad",
"Android Developer");
listItems.add(listItem);
ListItem listItem1 = new ListItem(
R.drawable.user,
"Malik",
"Developer");
listItems.add(listItem1);
adapter = new MyAdapter(listItems, this);
recyclerView.setAdapter(adapter);
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
TextView userName = (TextView) findViewById(R.id.loggedInName);
userName.setText(getSinchServiceInterface().getUserName());
//mCallButton.setEnabled(true);
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
//to kill the current session of SinchService
private void stopButtonClicked() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finish();
}
//to place the call to the entered name
public void callButtonClicked(String user) {
//String userName = mCallName.getText().toString();
if (user.isEmpty()) {
Toast.makeText(this, "Please enter a user to call", Toast.LENGTH_LONG).show();
return;
}
Call call = getSinchServiceInterface().callUserVideo(user);
String callId = call.getCallId();
Intent callScreen = new Intent(this, CallScreenActivity.class);
callScreen.putExtra(SinchService.CALL_ID, callId);
startActivity(callScreen);
}
private OnClickListener buttonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.callButton:
String str = MyAdapter.getStr();
Toast.makeText(PlaceCallActivity.this, "" + str, Toast.LENGTH_SHORT).show();
//callButtonClicked(str);
break;
case R.id.stopButton:
stopButtonClicked();
break;
}
}
};
}
and MyAdapter Class:
package techheromanish.example.com.videochatapp;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ListItem> listItems;
private Context context;
private static String str;
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final ListItem listItem = listItems.get(position);
holder.imageViewProfile.setImageResource(listItem.getImage());
holder.textViewName.setText(listItem.getName());
holder.textViewBio.setText(listItem.getBio());
/*Picasso.with(context)
.load(listItem.getImageUrl())
.into(holder.imageView);
*/
// str = listItem.getName();
holder.callButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "You Clicked " + listItem.getName(), Toast.LENGTH_SHORT).show();
PlaceCallActivity placeCallActivity = new PlaceCallActivity();
placeCallActivity.callButtonClicked(listItem.getName());
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName, textViewBio;
public ImageView imageViewProfile;
public Button callButton;
ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewBio = (TextView) itemView.findViewById(R.id.textViewBio);
imageViewProfile = (ImageView) itemView.findViewById(R.id.imageViewProfile);
callButton = (Button) itemView.findViewById(R.id.callButton);
}
}
public static String getStr() {
return str;
}
}
In this adapter I am using button to call from PlaceCallActivity.
Please change this:
private RecyclerView.Adapter adapter;
to this:
private MyAdapter adapter;
creating an instance of an activity wouldn't make it go through its lifecycle; if the declaration of the properties which are necessary to make the code run is dependent on your activity's lifecycle then calling the method on the properly initialized activity instance should solve this.
MyAdapter class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ListItem> listItems;
private Context context;
private PlaceCallActivity placeCallActivity;
private static String str;
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
// this.placeCallActivity now references the parent activity instance
this.placeCallActivity=(PlaceCallActivity)context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final ListItem listItem = listItems.get(position);
holder.imageViewProfile.setImageResource(listItem.getImage());
holder.textViewName.setText(listItem.getName());
holder.textViewBio.setText(listItem.getBio());
/*Picasso.with(context)
.load(listItem.getImageUrl())
.into(holder.imageView);
*/
// str = listItem.getName();
holder.callButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "You Clicked " + listItem.getName(), Toast.LENGTH_SHORT).show();
placeCallActivity.callButtonClicked(listItem.getName());
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName, textViewBio;
public ImageView imageViewProfile;
public Button callButton;
ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewBio = (TextView) itemView.findViewById(R.id.textViewBio);
imageViewProfile = (ImageView) itemView.findViewById(R.id.imageViewProfile);
callButton = (Button) itemView.findViewById(R.id.callButton);
}
}
public static String getStr() {
return str;
}
}
you can create an interface:
public interface CallButtonClickListener{
void onButtonClicked(String name);
}
Edit
public class PlaceCallActivity extends BaseActivity {
private Button mCallButton;
private EditText mCallName;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
//new code
private CallButtonClickListener buttonListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainn);
//initializing UI elements
//mCallName = (EditText) findViewById(R.id.callName);
mCallButton = (Button) findViewById(R.id.callButton);
//mCallButton.setEnabled(false);
//mCallButton.setOnClickListener(buttonClickListener);
Button stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setOnClickListener(buttonClickListener);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
listItems = new ArrayList<>();
// loadRecyclerViewData();
ListItem listItem = new ListItem(
R.drawable.user,
"Jawad",
"Android Developer");
listItems.add(listItem);
ListItem listItem1 = new ListItem(
R.drawable.user,
"Malik",
"Developer");
listItems.add(listItem1);
//implement the logic there
adapter = new MyAdapter(listItems, this, new CallButtonClickListener(){
#Override
public void onButtonClicked(String name){
//your code here.
}
});
recyclerView.setAdapter(adapter);
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
TextView userName = (TextView) findViewById(R.id.loggedInName);
userName.setText(getSinchServiceInterface().getUserName());
//mCallButton.setEnabled(true);
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
//to kill the current session of SinchService
private void stopButtonClicked() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finish();
}
//to place the call to the entered name
public void callButtonClicked(String user) {
//String userName = mCallName.getText().toString();
if (user.isEmpty()) {
Toast.makeText(this, "Please enter a user to call", Toast.LENGTH_LONG).show();
return;
}
Call call = getSinchServiceInterface().callUserVideo(user);
String callId = call.getCallId();
Intent callScreen = new Intent(this, CallScreenActivity.class);
callScreen.putExtra(SinchService.CALL_ID, callId);
startActivity(callScreen);
}
private OnClickListener buttonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.callButton:
String str = MyAdapter.getStr();
Toast.makeText(PlaceCallActivity.this, "" + str, Toast.LENGTH_SHORT).show();
//callButtonClicked(str);
break;
case R.id.stopButton:
stopButtonClicked();
break;
}
}
};
}
Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ListItem> listItems;
private Context context;
private static String str;
private CallButtonClickListener buttonListener;
public MyAdapter(List<ListItem> listItems, Context context, CallButtonClickListener buttonListener) {
this.listItems = listItems;
this.context = context;
this.buttonListener = buttonListner;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final ListItem listItem = listItems.get(position);
holder.imageViewProfile.setImageResource(listItem.getImage());
holder.textViewName.setText(listItem.getName());
holder.textViewBio.setText(listItem.getBio());
/*Picasso.with(context)
.load(listItem.getImageUrl())
.into(holder.imageView);
*/
// str = listItem.getName();
holder.callButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "You Clicked " + listItem.getName(), Toast.LENGTH_SHORT).show();
buttonListener.onButtonClicked(listItem.getName());
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName, textViewBio;
public ImageView imageViewProfile;
public Button callButton;
ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewBio = (TextView) itemView.findViewById(R.id.textViewBio);
imageViewProfile = (ImageView) itemView.findViewById(R.id.imageViewProfile);
callButton = (Button) itemView.findViewById(R.id.callButton);
}
}
public static String getStr() {
return str;
}
}

attempting to use incompatible return type

Can someone help me with this error that I keep getting? The program that I'm trying to implement admob banner ad between items in recyclerview. every thing is ok but still this one error that blocked me from go on.
public class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.ViewHolder> {
public static final String TAG = RecipeAdapter.class.getSimpleName();
public static final HashMap<String, Integer> LABEL_COLORS = new HashMap<String, Integer>() {{
put("Low-Carb", R.color.colorLowCarb);
put("Low-Fat", R.color.colorLowFat);
put("Low-Sodium", R.color.colorLowSodium);
put("Medium-Carb", R.color.colorMediumCarb);
put("Vegetarian", R.color.colorVegetarian);
put("Balanced", R.color.colorBalanced);
}};
private Context mContext;
private LayoutInflater mInflater;
private ArrayList<Recipe> mDataSource;
private static final int DEFAULT_VIEW_TYPE = 1;
private static final int NATIVE_AD_VIEW_TYPE = 2;
public RecipeAdapter(Context context, ArrayList<Recipe> items) {
mContext = context;
mDataSource = items;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
#Override public int getItemViewType(int position) {
// Change the position of the ad displayed here. Current is after 5
if ((position + 1) % 6 == 0) {
return NATIVE_AD_VIEW_TYPE;
}
return DEFAULT_VIEW_TYPE; }
#NonNull
#Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
switch (viewType) {
default:
view = layoutInflater
.inflate(R.layout.list_item_native_ad, parent, false);
return new ViewHolder(view);
case NATIVE_AD_VIEW_TYPE:
view = layoutInflater.inflate(R.layout.list_item_native_ad, parent, false);
return new ViewHolderAdMob(view);
}
}
#Override public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
// Get relevant subviews of row view
TextView titleTextView = holder.titleTextView;
TextView subtitleTextView = holder.subtitleTextView;
TextView detailTextView = holder.detailTextView;
ImageView thumbnailImageView = holder.thumbnailImageView;
//Get corresponding recipe for row final Recipe recipe = (Recipe) getItem(position);
// Update row view's textviews to display recipe information
titleTextView.setText(recipe.title);
subtitleTextView.setText(recipe.description);
detailTextView.setText(recipe.label);
// Use Picasso to load the image. Temporarily have a placeholder in case it's slow to load
Picasso.with(mContext).load(recipe.imageUrl).placeholder(R.mipmap
.ic_launcher).into(thumbnailImageView);
holder.parentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent detailIntent = new Intent(mContext, RecipeDetailActivity.class);
detailIntent.putExtra("title", recipe.title);
detailIntent.putExtra("url", recipe.instructionUrl);
mContext.startActivity(detailIntent);
}
});
// Style text views
Typeface titleTypeFace = Typeface.createFromAsset(mContext.getAssets(),
"fonts/JosefinSans-Bold.ttf");
titleTextView.setTypeface(titleTypeFace);
Typeface subtitleTypeFace = Typeface.createFromAsset(mContext.getAssets(),
"fonts/JosefinSans-SemiBoldItalic.ttf");
subtitleTextView.setTypeface(subtitleTypeFace);
Typeface detailTypeFace = Typeface.createFromAsset(mContext.getAssets(),
"fonts/Quicksand-Bold.otf");
detailTextView.setTypeface(detailTypeFace);
detailTextView.setTextColor(android.support.v4.content.ContextCompat.getColor(mContext, LABEL_COLORS
.get(recipe.label)));
}
#Override public int getItemCount() {
return mDataSource.size(); }
#Override public long getItemId(int position) {
return position; }
public Object getItem(int position) {
return mDataSource.get(position); }
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView titleTextView;
private TextView subtitleTextView;
private TextView detailTextView;
private ImageView thumbnailImageView; private View parentView;
public ViewHolder(#NonNull View view){
super(view);
// create a new "Holder" with subviews
this.parentView = view;
this.thumbnailImageView = (ImageView) view.findViewById(R.id.recipe_list_thumbnail);
this.titleTextView = (TextView) view.findViewById(R.id.recipe_list_title);
this.subtitleTextView = (TextView) view.findViewById(R.id.recipe_list_subtitle);
this.detailTextView = (TextView) view.findViewById(R.id.recipe_list_detail);
// hang onto this holder for future recyclage
view.setTag(this);
}
}
public class ViewHolderAdMob extends RecyclerView.ViewHolder {
private final AdView mNativeAd;
public ViewHolderAdMob(View itemView) {
super(itemView);
mNativeAd = itemView.findViewById(R.id.nativeAd);
mNativeAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdLoaded");
// }
}
#Override
public void onAdClosed() {
super.onAdClosed();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdClosed");
// }
}
#Override
public void onAdFailedToLoad(int errorCode) {
super.onAdFailedToLoad(errorCode);
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdFailedToLoad");
// }
}
#Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdLeftApplication");
// }
}
#Override
public void onAdOpened() {
super.onAdOpened();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdOpened");
// }
}
});
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice("") // Remove this before publishing app
.build();
mNativeAd.loadAd(adRequest);
}
}
}
The return type needs to be whatever ViewHolder type you declared for your adapter class.
For example, from the Android RecyclerView example page:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
// ^^^^^^^^^^^^^^^^^^^^^^
// It should return this type ^
public static class MyViewHolder extends RecyclerView.ViewHolder {
// your adapter
}
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
// Note: returns MyAdapter.MyViewHolder, not RecyclerView.ViewHolder
}
}
In your case, you have
public class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.ViewHolder>
which means your onCreateViewHolder has to return RecipeAdapter.ViewHolder not RecyclerView.ViewHolder.
There is a separate issue too, which is that you have two ViewHolder types in the same adapter. To do this, you would need to change the ViewHolder type that your RecyclerView is based on to the generic type (RecyclerView.ViewHolder).
Please review this question, it has good answers for how to do this.

recyclerview onclicklistener java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

when I dynamic remove an item, or when I refresh the adapter(swipe to fresh) i get these erros:
recyclerview onclicklistener java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
Really can't figure out why this is happening, Really Appreciate any feed back.
MainActivity:
adapter.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
GroupModel selectedList = mGroupModels.get(position);
if (selectedList != null) {
Log.d(TAG, "setAdpterListner > view.getId: " + view.getId() +
" | P: " + position +
" | data ID: " + selectedList.getGroupName()
//" | viewID: " + viewID
);
Intent intent = new Intent(this, DetailsActivity.class);
String listId = selectedList.getGroupID();
String listName = selectedList.getGroupName();
intent.putExtra(Constant.KEY_LIST_ID, listId);
intent.putExtra(Constant.KEY_LIST_NAME, listName);
startActivity(intent);
}
}
});
Adapter:
public class GroupListAdapter extends RecyclerView.Adapter<GroupListAdapter.StatusViewHolder> {
Context context;
private List<GroupModel> mGroupModels;
private static OnItemClickListener listener;
public GroupListAdapter(Context context, List<GroupModel> groupList) {
this.context = context;
this.mGroupModels = groupList;
}
public void setOnItemClickListener(OnItemClickListener listener) {
GroupListAdapter.listener = listener;
}
#Override
public StatusViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_group_list, parent, false);
return new StatusViewHolder(view);
}
#Override
public void onBindViewHolder(StatusViewHolder holder, int position) {
final GroupModel data = mGroupModels.get(position);
holder.text_view_list_name.setText(data.getGroupName());
}//end onBindViewHolder
#Override
public int getItemCount() {
return mGroupModels.size();
}
public class StatusViewHolder extends RecyclerView.ViewHolder {
public TextView text_view_list_name;
public TextView created_by;
public StatusViewHolder(final View itemView) {
super(itemView);
text_view_list_name = (TextView) itemView.findViewById(R.id.text_view_list_name);
created_by = (TextView) itemView.findViewById(R.id.created_by);
// Setup the click listener
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
}
}//end StatusViewHolder
}//end GroupListAdapter
UPDATE:
I taken into consideration Yurii Tsap Feedback. I check the code again. I think the problem is somewhere below:
Whenever I swipe to Fresh, and If i click on the list straight way, the app Crash with the error from above.
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// Refresh items
mRecyclerView.invalidate();
adapter = null;
initGetGroupList();
mSwipeRefreshLayout.setRefreshing(false);
}
});
In the API call
...
GroupModel groupModel = new GroupModel(groupID, groupName, groupCreatedBy);
mGroupModels.add(groupModel);
}
updateUI(true);
if (adapter == null) {
adapter = new GroupListAdapter(MainActivity.this, mGroupModels);
mRecyclerView.setAdapter(adapter);
setAdapterListener(adapter);
}
The problem is definitely not in the static listener. And also the listener is just an interface callback(related to the comment above) not a AdapterView.OnItemClickListener(). I think the problem is somewhere behind this code, maybe you are clearing the item list somewhere else or something like that?
And also as for me in your case it's better to use getAdapterPosition() instead of getLayoutPosition().
As mentioned in docs :
If LayoutManager needs to call an external method that requires the adapter position of the item, it can use getAdapterPosition() or RecyclerView.Recycler.convertPreLayoutPositionToPostLayout(int).
Make OnItemClickListener non static .Like
private OnItemClickListener listener;
your code have alot of problem
i will explain my way to handle recycle view
very simple adapter
package com.pentavalue.ongo.transportway.adapter;
import android.app.Activity;
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.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import com.pentavalue.ongo.R;
import com.pentavalue.ongo.Utilts.ImageLoaderHelper;
import com.pentavalue.ongo.register.model.Vechiles;
import com.pentavalue.ongo.widget.ArabicTextView;
import java.util.ArrayList;
/**
* Created by hamada on 19/09/2015.
*/
public class TransportTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public LayoutInflater inflater = null;
Activity activity;
ArrayList<Vechiles> vechileList;
ImageLoaderHelper imageLoaderHelper;
public TransportTypeAdapter(Activity activity, ArrayList<Vechiles> vechileList) {
this.activity = activity;
this.vechileList = vechileList;
imageLoaderHelper = new ImageLoaderHelper(activity, null);
inflater = LayoutInflater.from(activity);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View vi = inflater.inflate(R.layout.single_transport_item, parent, false);
RecyclerView.ViewHolder vh = new VechileListHolder(vi);
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int pos) {
VechileListHolder mHolder = (VechileListHolder) viewHolder;
mHolder.renderDate(vechileList.get(pos));
}
#Override
public int getItemCount() {
if (vechileList != null)
return this.vechileList.size();
else
return 0;
}
public class VechileListHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
ArabicTextView vecName;
RelativeLayout img_layout;
ProgressBar progress;
ImageView imgView;
public VechileListHolder(View vi) {
super(vi);
vi.setOnClickListener(this);
img_layout = (RelativeLayout) vi.findViewById(R.id.img_layout);
vecName = (ArabicTextView) vi.findViewById(R.id.TVVecName);
progress = (ProgressBar) vi.findViewById(R.id.progress);
imgView = (ImageView) vi.findViewById(R.id.imgView);
}
public void renderDate(Vechiles item) {
imageLoaderHelper.loadImage(imgView, progress, item.getImg());
vecName.setText(item.getVecName());
}
#Override
public void onClick(View v) {
if (mItemClickListener != null)
mItemClickListener.onItemClickListener(getPosition(), v);
}
}
public void setOnItemClickListener(ItemClickListener itemClick) {
this.mItemClickListener = itemClick;
}
public ItemClickListener mItemClickListener;
public interface ItemClickListener {
public void onItemClickListener(int pos, View v);
}
public void updateList(ArrayList<Vechiles> vechileList) {
this.vechileList = vechileList;
notifyDataSetChanged();
}
public void removeItem(int pos){
this.vechileList.remove(pos);
notifyItemRemoved(pos);
}
}
and in Fragment or activity can
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initListView();
}
private void initRecycleView(){
listView = (RecyclerView) v.findViewById(R.id.listView);
listView.getItemAnimator().setAddDuration(1000);
listView.getItemAnimator().setChangeDuration(1000);
listView.getItemAnimator().setMoveDuration(1000);
listView.getItemAnimator().setRemoveDuration(1000);
listView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
listView.setAdapter(new TransportTypeAdapter(getActivity(), vecList));
}
then after data back from API can update adapter with new data by use method update
((VechileListHolder ) listView.getAdapter).updateList( vechileList);
in case went to remove any item by using Pos can do call method that in adapter removeItem(pos)
((VechileListHolder ) listView.getAdapter).removeItem(1);
hope this code help you

Blank between item's recyclerView when scrollToPositionWithOffset with layoutManager

I have a little problem with one of my RecyclerView.
In fact, it contains another RecyclerView in each of his items, and when I tried to scroll using LinearLayoutManager on my global RecyclerView (listener onClick on row), a blank space appears between second RecyclerView's item of the first and last item.
A screen of the problem (sorry for my crappy english).
My first RecyclerView adapter :
package com.ylly.hypred.process.adapter;
/**
* Created by YLLY on 24/06/2015.
*/
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.ylly.hypred.R;
import com.ylly.hypred.custom.HypredToast;
import com.ylly.hypred.custom.MyTextView;
import com.ylly.hypred.custom.RecyclerItemClickListener;
import com.ylly.hypred.dao.Etape;
import com.ylly.hypred.dao.Produit;
import com.ylly.hypred.dao.Protocole;
import com.ylly.hypred.db.HypredDbManager;
import com.ylly.hypred.process.atelierProcess.AtelierProcessModeleUn;
import com.ylly.hypred.process.recyclerView.SpacesItemDecoration;
import org.solovyev.android.views.llm.LinearLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class AdapterProtocole extends RecyclerView.Adapter<AdapterProtocole.ViewHolder> implements AdapterEtape.clickOnProductListener {
private ArrayList<Protocole> protocoleArrayList;
private Context context;
private clickOnProductListener mCallback;
public AdapterProtocole(ArrayList<Protocole> protocoleArrayList, Context context) {
this.protocoleArrayList = protocoleArrayList;
this.context = context;
}
public interface clickOnProductListener {
void appelProduit(long productId);
void ajouterAllProduit(ArrayList<Produit> produitArrayList);
void ajouterProduit(Produit produit);
}
// Create new views (invoked by the layout manager)
#Override
public AdapterProtocole.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout_process_protocole, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
View view = new View(context);
viewHolder.labelProtocoleTextView.setText(protocoleArrayList.get(position).getName());
viewHolder.produitsRecyclerView.addItemDecoration(new SpacesItemDecoration(0, 0, 0, 10));
viewHolder.produitsRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
final ArrayList<Etape> fEtapeArrayList = new ArrayList<>();
Log.d("AdapterProtocole", "id des étapes du protocole " + protocoleArrayList.get(position).getName() + " = " +
protocoleArrayList.get(position).getEtapeId() + "," +
protocoleArrayList.get(position).getEtapeTwoId() + "," +
protocoleArrayList.get(position).getEtapeThreeId() + "," +
protocoleArrayList.get(position).getEtapeFourId() + "," +
protocoleArrayList.get(position).getEtapeFiveId() + "," +
protocoleArrayList.get(position).getEtapeSixId() + ".");
String test = "listes etapes dispo :";
List<Etape> etapes = HypredDbManager.getDbManager().getEtapeDbManager().getAllEtape();
for(int i=0; i<etapes.size(); i++) {
test += etapes.get(i).getId() + ",";
}
Log.d("AdapterProtocole", test);
if (HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeId()) != null) {
fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeId()));
}
if (HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeTwoId()) != null) {
fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeTwoId()));
}
if (HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeThreeId()) != null) {
fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeThreeId()));
}
if (HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeFourId()) != null) {
fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeFourId()));
}
if (HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeFiveId()) != null) {
fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeFiveId()));
}
if (HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeSixId()) != null) {
fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
.getEtapeById(protocoleArrayList.get(position).getEtapeSixId()));
}
Log.d("AdapterProtocole", Integer.toString(fEtapeArrayList.size()));
final AdapterEtape etapeAdapter = new AdapterEtape(fEtapeArrayList, view.getContext());
etapeAdapter.setClickOnProductListener(new AdapterEtape.clickOnProductListener() {
#Override
public void appelerProduit(long produitId) {
mCallback.appelProduit(produitId);
}
#Override
public void ajouterProduitSelection(Produit produit) {
mCallback.ajouterProduit(produit);
}
});
viewHolder.produitsRecyclerView.setAdapter(etapeAdapter);
viewHolder.imageViewPanierSelectionAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<Produit> produits = new ArrayList<>();
for (int i = 0; i < fEtapeArrayList.size(); i++) {
produits.add((fEtapeArrayList.get(i).getProduit()));
}
mCallback.ajouterAllProduit(produits);
HypredToast.makeText(context, "Produits ajoutés au panier avec succès.", Toast.LENGTH_SHORT).show();
}
});
}
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder {
public MyTextView labelProtocoleTextView;
public RecyclerView produitsRecyclerView;
public ImageView imageViewPanierSelectionAll;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
labelProtocoleTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_protocole_label_text_view);
produitsRecyclerView = (RecyclerView) itemLayoutView.findViewById(R.id.item_layout_protocole_recycler_view);
imageViewPanierSelectionAll = (ImageView) itemLayoutView.findViewById(R.id.item_layout_process_protocole_panier_rouge);
}
}
// Return the size of your itemsData (invoked by the layout manager)
#Override
public int getItemCount() {
return protocoleArrayList.size();
}
#Override
public void appelerProduit(long produitId) {
}
public void setClickOnProductListener(clickOnProductListener callback) {
mCallback = callback;
}
#Override
public void ajouterProduitSelection(Produit produit) {
}
}
My inside RecyclerView :
package com.ylly.hypred.process.adapter;
/**
* Created by YLLY on 20/07/2015.
*/
import android.content.Context;
import android.graphics.Paint;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.ylly.hypred.R;
import com.ylly.hypred.custom.HypredToast;
import com.ylly.hypred.custom.MyTextView;
import com.ylly.hypred.dao.Etape;
import com.ylly.hypred.dao.Produit;
import com.ylly.hypred.db.HypredDbManager;
import com.ylly.hypred.process.atelierProcess.AtelierProcessModeleUn;
import java.util.ArrayList;
public class AdapterEtape extends RecyclerView.Adapter<AdapterEtape.ViewHolder> {
private ArrayList<Etape> etapeArrayList;
private Context context;
private clickOnProductListener mCallback;
public interface clickOnProductListener {
void appelerProduit(long produitId);
void ajouterProduitSelection(Produit produit);
}
public AdapterEtape(ArrayList<Etape> etapeArrayList, Context context) {
this.etapeArrayList = etapeArrayList;
this.context = context;
}
// Create new views (invoked by the layout manager)
#Override
public AdapterEtape.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout_process_etape, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
viewHolder.labelEtapeTextView.setText(etapeArrayList.get(position).getTexte_etape());
if(HypredDbManager.getDbManager().getProductDbManager().
getProduitById(etapeArrayList.get(position).getProduitId())!=null) {
viewHolder.labelProduitTextView
.setText(HypredDbManager.getDbManager().getProductDbManager().
getProduitById(etapeArrayList.get(position).getProduitId()).getNom_produit());
}
viewHolder.labelProduitTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallback.appelerProduit(etapeArrayList.get(position).getProduitId());
}
});
viewHolder.descriptifTextView.setText(etapeArrayList.get(position).getTemps() + "/" +
etapeArrayList.get(position).getConcentration() + "/" + etapeArrayList.get(position).getTemperature());
int temp = 1 + position;
if (etapeArrayList.size() == temp && etapeArrayList.get(position).getRincage()) {
viewHolder.imageViewEtapeSuivante.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.hypred_protocole_vague_finale));
} else if(etapeArrayList.get(position).getRincage()) {
viewHolder.imageViewEtapeSuivante.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.hypred_protocole_vague));
}
viewHolder.imageViewPanierSelection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallback.ajouterProduitSelection(etapeArrayList.get(position).getProduit());
HypredToast.makeText(context, "Produit ajouté au panier avec succès.", Toast.LENGTH_SHORT).show();
}
});
}
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder {
public MyTextView labelEtapeTextView;
public MyTextView labelProduitTextView;
public MyTextView descriptifTextView;
public ImageView imageViewEtapeSuivante;
public ImageView imageViewPanierSelection;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
labelEtapeTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_etape_label_etape_text_view);
labelProduitTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_etape_label_produit_text_view);
descriptifTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_etape_descriptif_text_view);
labelProduitTextView.setPaintFlags(labelProduitTextView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
imageViewEtapeSuivante = (ImageView) itemLayoutView.findViewById(R.id.item_layout_etape_vague_image_view);
imageViewPanierSelection = (ImageView) itemLayoutView.findViewById(R.id.item_layout_etape_panier_image_view);
}
}
public Etape getEtape(int position) {
Etape etape = etapeArrayList.get(position);
return etape;
}
// Return the size of your itemsData (invoked by the layout manager)
#Override
public int getItemCount() {
return etapeArrayList.size();
}
public void setClickOnProductListener(clickOnProductListener callback) {
mCallback = callback;
}
}
My function which define the Protocole RecyclerView and the rows for scrolling :
public void initProtocole(View v, final FragmentProtocoles protocoleFragment, ArrayList<Protocole> protocoleArrayList) {
super.initProtocole(v, protocoleFragment, protocoleArrayList);
initFrameLayout(v, R.id.fragment_protocole_container, R.layout.view_process_protocole_rep);
ArrayList<Protocole> fProtocoleArrayList = new ArrayList<>();
for (int i = 0; i < protocoleArrayList.size(); i++) {
fProtocoleArrayList.add(protocoleArrayList.get(i));
}
final RecyclerView recyclerView = (RecyclerView) v.findViewById(R.id.protocole_rep_recycler_view);
recyclerView.addItemDecoration(new SpacesItemDecoration(25, 25, 25, 25));
final LinearLayoutManager mLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(mLayoutManager);
AdapterProtocole adapterProtocole = new AdapterProtocole(fProtocoleArrayList, v.getContext());
adapterProtocole.setClickOnProductListener(new AdapterProtocole.clickOnProductListener() {
#Override
public void appelProduit(long productId) {
protocoleFragment.appelProduit(HypredDbManager.getDbManager().getProductDbManager().getProduitById(productId));
}
#Override
public void ajouterAllProduit(ArrayList<Produit> produitArrayList) {
for (int i = 0; i < produitArrayList.size(); i++) {
SelectionManager.getInstance().addProductToSelection(produitArrayList.get(i));
}
}
#Override
public void ajouterProduit(Produit produit) {
SelectionManager.getInstance().addProductToSelection(produit);
}
});
recyclerView.setAdapter(adapterProtocole);
ImageView imageViewProtocoleFlecheGauche = (ImageView) v.findViewById(R.id.protocole_rep_fleche_gauche);
imageViewProtocoleFlecheGauche.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RecyclerViewPositionHelper recyclerViewPositionHelper = RecyclerViewPositionHelper.createHelper(recyclerView);
int firstVisibleItem = recyclerViewPositionHelper.findFirstCompletelyVisibleItemPosition();
if (firstVisibleItem != 0) {
mLayoutManager.scrollToPositionWithOffset(firstVisibleItem - 1, 0);
}
}
});
ImageView imageViewProtocoleFlecheDroite = (ImageView) v.findViewById(R.id.protocole_rep_fleche_droite);
imageViewProtocoleFlecheDroite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RecyclerViewPositionHelper recyclerViewPositionHelper = RecyclerViewPositionHelper.createHelper(recyclerView);
int lastVisibleItem = recyclerViewPositionHelper.findLastCompletelyVisibleItemPosition();
int firstVisibleItem = recyclerViewPositionHelper.findFirstCompletelyVisibleItemPosition();
if (lastVisibleItem != recyclerViewPositionHelper.getItemCount() - 1) {
mLayoutManager.scrollToPositionWithOffset(firstVisibleItem + 1, 0);
}
}
});
}
Thanks in advance :)
I also face the same problem, you need to change your RecyclerView adapter::
Now it is like this in your code::
// Create new views (invoked by the layout manager)
#Override
public AdapterEtape.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout_process_etape, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
You need to change like this::
// Create new views (invoked by the layout manager)
#Override
public AdapterEtape.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout_process_etape, parent, false);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}

Categories

Resources