In first line the parameter int position in onBindViewHolder gives error i set it to final int position but still its not working - android-recyclerview

public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.title1.setText(data1[position]);
holder.releasedyear.setText(data2[position]);
holder.catogery.setText(data3[position]);
holder.myimg.setImageResource(images[position]);
holder.mainlayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, MainActivity2.class) ;
intent.putExtra("data1", data1[position]) ;
intent.putExtra("data2", data2[position]) ;
intent.putExtra("data3", data3[position]) ;
intent.putExtra("myImage", images[position]);
context.startActivity(intent);
}
});
}
In first line the parameter int position in onBindViewHolder gives error i set it to final int position but still its not working

Related

How to track randomly displayed drawable to cross check with user submitted answer

I am trying to create an application where a random image is displayed(Working), and the user selects from a dropdown list the displayed image and this is checked to see if it is correct or not
I am not sure how to track the image displayed as I need something to reference in my if statement
See below my attempt but it returns null on the locationOfCorrectAnswer
public class IdentifyTheBrandActivity extends AppCompatActivity implements AdapterView.OnItemClickListener,
AdapterView.OnItemSelectedListener { String[] Brands = { "Audi", "Bentley", "BMW" };
Button SubmitButton;
ImageView imageView;
int[] images;
int chosenCar = 0;
int locationOfCorrectAnswer;
String[] answers = new String[3];
ArrayList<String> carBrands = new ArrayList<>();
public void brandChosen(View view) {
if (view.getTag().toString().equals(Integer.toString(locationOfCorrectAnswer))){
Toast.makeText(getApplicationContext(), "Correct", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "Wrong it was " + carBrands.get(chosenCar), Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_identify_the_brand);
imageView = findViewById(R.id.RandomImage);
imageView.setTag("bg");
carBrands.add("Audi");
carBrands.add("Bentley");
carBrands.add("BMW");
images = new int[]{R.drawable.audi_a3_2010_27_17_200_20_4_77_56_169_21_fwd_5_4_4dr_igm, R.drawable.bentley_bentayga_2017_229_21_600_60_12_78_68_202_12_awd_5_4_suv_cce,
R.drawable.bmw_6_series_2014_82_18_310_30_6_74_53_192_20_rwd_4_2_convertible_mua};
Random random = new Random();
chosenCar = random.nextInt(images.length);
locationOfCorrectAnswer = random.nextInt(images.length);
imageView.setBackgroundResource(images[chosenCar]);
int incorrectAnswerLocation;
//Get a random between 0 and images.length-1
//int imageId = (int) (Math.random() * images.length);
Spinner spin = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, Brands);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(adapter);
spin.setOnItemSelectedListener(this);
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long l) {
Toast.makeText(getApplicationContext(), "Selected Brand: " + Brands[position]
,Toast.LENGTH_SHORT).show();
/*SubmitButton = findViewById(R.id.SubmitButton);
SubmitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Toast.makeText(getApplicationContext(), "Correct Brand", Toast.LENGTH_SHORT).show();
}
});*/
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
I'm not sure why my brandChosen method is returning null? I believe this is the approach that will work

Highlighted Items in reyclerview lose their state when scolling

I am trying to highlight clicked items in recylerview but as soon as when you scroll the highlighted items do not stay highlighted anymore. I do not know how to keep their state when scrolling. The implementation in the adapter class and given below:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>{
boolean isEnable = false;
List<ItemFiles> selectList = new ArrayList<>();
public MyAdapter.MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout._main,parent,false);
return new MyViewHolder(view);
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int
position) {
holder.item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isEnabled) {
ClickItem(holder);
}
}
private void ClickItem(MyHolder holder) {
ItemFiles s = files.get(holder.getAdapterPosition());
if (holder.highlightItem.getVisibility() == View.GONE){
holder.highlightItem.setVisibility(View.VISIBLE);
holder.highlightItem.setBackgroundColor(Color.LTGRAY);
selectList.add(s);
// this is what I tried to keep the highlighted state but no result
selectList.get(holder.getAdapterPosition()).setSelected(true);
} else {
holder.highlightItem.setVisibility(View.GONE);
holder.highlightItem.setBackgroundColor(Color.TRANSPARENT);
selectList.remove(s);
selectList.get(holder.getAdapterPosition()).setSelected(false);
}
}
}

Unable to Pass Data from RecyclerView Adapter to Viewpager Adapter

I am creating simple image gallery app in which images are shown on MainActivity inside RecyclerView and on click of Any Image it will take us to SlideActivity in which I want to show images on ViewPager and then we swipe all images should be shown on ViewPager. For retrieving images i am using Glide. Images Load on RecyclerView Perfectly Fine but when i click on any Image i get this Exception "java.lang.ArrayIndexOutOfBoundsException: length=15; index=-1".
I know there are many same questions like this I saw all codes but did not understood so finally decided to ask question I am pasting code whatever i tried till now. Any Suggestion or advice will be helpful bcz I work alone I have no Mentor and I am Learning. Thank you!
Error :
java.lang.ArrayIndexOutOfBoundsException: length=15; index=-1
at java.util.ArrayList.get(ArrayList.java:439)
at com.starmoonsolutions.imagegallery.RecycleViewAdapter$ViewHolder$1.onClick(RecycleViewAdapter.java:63)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24697)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
ImageUrl.java
public class ImageUrl {
String imageUrl;
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
RecyclerView recyclerView;
GridLayoutManager gridLayoutManager;
ArrayList<ImageUrl> imageUrlList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
recyclerView = findViewById(R.id.recyclerView);
gridLayoutManager = new GridLayoutManager(getApplicationContext(), 2);
recyclerView.setLayoutManager(gridLayoutManager);
imageUrlList = prepareData();
RecycleViewAdapter galleryAdapter = new RecycleViewAdapter(getApplicationContext(), imageUrlList);
recyclerView.setAdapter(galleryAdapter);
}
private ArrayList prepareData(){
// here you should give your image URLs and that can be a link from the Internet
String imageUrls[] = {
"https://images.pexels.com/photos/358457/pexels-photo-358457.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
"https://images.pexels.com/photos/934964/pexels-photo-934964.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/1202887/pexels-photo-1202887.jpeg?auto=compress&cs=tinysrgb&h=650&w=940",
"https://images.pexels.com/photos/337909/pexels-photo-337909.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/894443/pexels-photo-894443.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/951325/pexels-photo-951325.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/1534411/pexels-photo-1534411.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/266436/pexels-photo-266436.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/1894350/pexels-photo-1894350.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/87009/earth-soil-creep-moon-lunar-surface-87009.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/1820563/pexels-photo-1820563.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
"https://images.pexels.com/photos/1274260/pexels-photo-1274260.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"
};
imageUrlList = new ArrayList<>();
for (int i = 0; i < imageUrls.length; i++) {
ImageUrl imageUrl = new ImageUrl();
imageUrl.setImageUrl(imageUrls[i]);
imageUrlList.add(imageUrl);
}
Log.d("MainActivity", "List count: " + imageUrlList.size());
return imageUrlList;
}
}
RecyclerViewAdapter:
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>{
private ArrayList<ImageUrl> imageUrls;
private Context context;
public RecycleViewAdapter(Context context, ArrayList<ImageUrl> imageUrls) {
this.imageUrls = imageUrls;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.image_layout, viewGroup, false);
return new ViewHolder(view);
}
/**
* gets the image url from adapter and passes to Glide API to load the image
*
* #param viewHolder
* #param i
*/
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
Glide.with(context).load(imageUrls.get(i).getImageUrl()).into(viewHolder.img);
}
#Override
public int getItemCount() {
return imageUrls.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
RecyclerView recyclerView;
ImageView img;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
img = itemView.findViewById(R.id.imageView);
recyclerView = itemView.findViewById(R.id.recyclerView);
final int pos = getAdapterPosition();
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, SlideActivity.class);
error point here-> intent.putExtra("image", String.valueOf(imageUrls.get(pos).getImageUrl())); <- error point here
intent.putExtra("position", pos);
intent.putExtra("list", imageUrls.get(pos).imageUrl);
context.startActivity(intent);
}
});
}
}
}
SlideActivity(ViewPager):
public class SlideActivity extends AppCompatActivity {
private ViewPager viewPager;
private Context context = SlideActivity.this;
private ViewPagerAdapter adapter;
private ArrayList<String> list;
String image;
private int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slide_activity);
viewPager = findViewById(R.id.viewPager);
getIntentInfo();
adapter = new ViewPagerAdapter(list,context);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem((position));
}
private void getIntentInfo() {
image = getIntent().getStringExtra("image");
list = getIntent().getStringArrayListExtra("list");
position = getIntent().getIntExtra("position",0);
}
}
ViewPagerAdapter:
public class ViewPagerAdapter extends PagerAdapter {
private ArrayList<String> imageUrls;
private android.content.Context context;
private LayoutInflater inflater;
private ImageView wallpaper;
public ViewPagerAdapter() {
}
public ViewPagerAdapter(ArrayList<String> imageUrls, android.content.Context context) {
this.imageUrls = imageUrls;
this.context = context;
}
#Override
public int getCount() {
return imageUrls.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object o) {
return view.equals(o);
}
#NonNull
#Override
public Object instantiateItem(#NonNull final ViewGroup container, final int position) {
inflater = LayoutInflater.from(container.getContext());
View view = inflater.inflate(R.layout.pager_item, container, false);
wallpaper = view.findViewById(R.id.walpaperImage);
Glide.with(context).asBitmap().load(imageUrls.get(position)).into(wallpaper);
container.addView(view, 0);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((View) object);
}
}
The problem is actually in getting the adapter position.
public ViewHolder(#NonNull final View itemView) {
super(itemView);
img = itemView.findViewById(R.id.imageView);
recyclerView = itemView.findViewById(R.id.recyclerView);
// remove the below line
//final int pos = getAdapterPosition();
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, SlideActivity.class);
// you need to freshly get the adapter position here.
int pos = getAdapterPosition();
error point here-> intent.putExtra("image", String.valueOf(imageUrls.get(pos).getImageUrl())); <- error point here
intent.putExtra("position", pos);
intent.putExtra("list", imageUrls.get(pos).imageUrl);
context.startActivity(intent);
}
});
}
Since ViewHolder gets recycled, adapter position can change therefore you need to get the latest adapter position inside your click listener.
And regarding the Bundle data, pass the list of URLs of 'String' type instead of the custom object,
public void onClick(View v) {
Intent intent = new Intent(context, SlideActivity.class);
error point here-> intent.putExtra("image", String.valueOf(imageUrls.get(pos).getImageUrl())); <- error point here
intent.putExtra("position", pos);
// imageUrls is of type ArrayList<String>
intent.putStringArrayListExtra("list", imageUrls);
context.startActivity(intent); }
or else use the Parcelable library to serialize the custom object.

setOnClickListener changes every seventh view in recyclerview

when i click an item in Recyclerview every seventh item gets the effect.
onBindViewHolder:
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.channelName.setText(list.get(position).getChannnelName());
holder.linearLayoutChannelName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
view.setBackgroundColor(Color.parseColor("#93bcff"));
}
});
}
public class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout linearLayoutChannelName;
TextView channelName;
public ViewHolder(View itemView) {
super(itemView);
channelName = itemView.findViewById(R.id.tv_channel_name);
linearLayoutChannelName = itemView.findViewById(R.id.ll_channelname);
}
}
when i click an item every seventh item changes its backgroung color,and it repeats every seventh item in the list, and even when scrolling across the list the background color dissapears.
https://i.stack.imgur.com/oq2sb.jpg
https://i.stack.imgur.com/rOzQg.jpg
Don't use onClickListener in onBindViewHolder instead set it in onCreateViewHolder and create a member variable to set the selected item. You can do it like this.
int mSelectedItemPosition = -1;
// in your createViewHolder method
holder.linearLayoutChannelName.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mSelectedItemPosition = position;
notifyItemRangeChanged(0, yourList.size());
}
}
});
And in your bind view holder check selected item position and set the background color
if(mSelectedItemPosition == position){
view.setBackgroundColor(Color.parseColor("#yourColor"))
}else{
view.setBackgroundColor(Color.parseColor("originalColor"));
}

RecycleView , some items' subView doesn't show correctly

in fragment
mAdapter = new MessageAdapter(this);
mRV.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false));
mRV.setItemAnimator(new DefaultItemAnimator());
DividerItemDecoration itemDecoration = new DividerItemDecoration.Builder()
.setOffsetLeft(ScreenUtil.dip2px(getActivity(), 60 + 10) + this.getResources().getDimensionPixelOffset(R.dimen.horizontal_margin))
.build(getActivity());
mRV.addItemDecoration(itemDecoration);
mRV.setItemViewCacheSize(15);
mRV.setAdapter(mAdapter);
in adapter
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MessageItemHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.w_message_item,parent,false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((RVItemInterface)holder).setAdapter(this);
((RVItemInterface)holder).update(dataList.get(position),position);
}
in holder
public class MessageItemHolder extends RecyclerView.ViewHolder implements RVItemInterface{
private RoundAvatar mAvatar;
private TextView mTitle;
private TextView mContent;
private TextView mTime;
private BaseRVAdapter mAdapter;
private MsgDecorVo mMsgDecorVo;
...
#Override
public void update(Object obj, final int position) {
reset();
mMsgDecorVo = (MsgDecorVo) obj;
if(mMsgDecorVo.type == MsgDecorVo.TYPE_CATEGORY){
updateCategory();
MsgVo msgVo = mMsgDecorVo.msgVo;
if(msgVo.getMsg() == null || msgVo.getMsg().equals("")){
mContent.setVisibility(View.GONE);
}else {
mContent.setVisibility(View.VISIBLE);
mContent.setText(msgVo.getMsg());
}
if(msgVo.getTime() == 0){
mTime.setVisibility(View.GONE);
}else {
mTime.setVisibility(View.VISIBLE);
mTime.setText(TimeUtil.transformLong2DateString(msgVo.getTime()));
}
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dealCategoryClick();
}
});
}else if(mMsgDecorVo.type == MsgDecorVo.TYPE_CONVERSATION){
...
mContent.setText(ImUtil.getMsgContent(message));
mTime.setText(TimeUtil.transformLong2DateString(message.getMsgTime()));
if(chatUserVo != null){
..
}else {
..
}
}
}
//
private void updateCategory(){
...
}
//
private void dealCategoryClick(){
...
}
#Override
public void setAdapter(RecyclerView.Adapter adapter) {
mAdapter = (BaseRVAdapter) adapter;
}
#Override
public void reset() {
mAvatar.setOnClickListener(null);
mAvatar.setAvatar(R.drawable.avatar_default_circle);
mAvatar.hideTagBottom();
mAvatar.hideTagTop();
}
}
these code in holder
mContent.setText(ImUtil.getMsgContent(message));
mTime.setText(TimeUtil.transformLong2DateString(message.getMsgTime()));
has run
but when I scrolled,some of items doesn't show correctly ,the time and content was gone!
if I notify the recyclerview ,it goes right, and if i scroll again,it will still be wrong
just like the image,you can see some items' (time & content) was gone!
http://g.picphotos.baidu.com/album/s%3D900%3Bq%3D90/sign=297cc7510946f21fcd345253c61f1a5d/a686c9177f3e6709378bcc5538c79f3df9dc5595.jpg "tooltip"
Well, you don't have the full code but I assume it is happening because you are not resetting your view states properly.
For Instance, in your updateCode, if type = TYPE_CATEGORY, you set the mTime's visibility depending on whether getTime is 0 or not. But as you scroll, that row might be re-used for
TYPE_CONVERSATION in which case, mTime's visibility will NOT be updated.