I am using recycler view in a fragment. Now I want to open a new fragment on recycler view item click. I have used the following code in my recycler view adapter. Please solve my problem.
public void onBindViewHolder(#NonNull MyViewHolder holder, final int position) {
holder.tv_name.setText(mData.get(position).getName());
holder.img.setImageResource(mData.get(position).getPhoto());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AppCompatActivity activity = (AppCompatActivity) v.getContext();
MiscellaneousFragment miscellaneousfragment = new MiscellaneousFragment();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.linerr, MiscellaneousFragment).addToBackStack(null).commit();
}
});
But I am getting this error in Logcat.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at androidx.fragment.app.FragmentTransaction.doAddOp.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MiscellaneousFragment miscellaneousfragment = new MiscellaneousFragment();
FragmentManager fragmentManager =currentfragment.getFragmentManager()
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction()
fragmentTransaction.add(R.id.linerr, miscellaneousfragment)
fragmentTransaction.addToBackStack(null)
fragmentTransaction.commit()
}
});
Related
I am trying to select items in recylerview. When I click an item, a checkbox appears on that item and it is highlighted. But the problem is that when I scroll, the item which is highlighted goes to its original color but the checkbox image remains as it should. Why the highlighted color is gone but the image remains after scrolling, I want the items to keep their state after scrolling.
public static List<Model> item = new ArrayList<Model>()
#Override
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int
position) {
holder.bind(item.get(position));
//
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.check);
public void bind(Model model) {
if (model.isChecked()){
imageView.setVisibility(View.VISIBLE);
itemView.setBackgroundColor(Color.GRAY);
model.setChecked(true);
} else {
imageView.setVisibility(View.GONE);
itemView.setBackgroundColor(Color.TRANSPARENT);
model.setChecked(false);
}
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Model s = item.get(getAdapterPosition());
if (!selectList.contains(s)){
selectList.add(s);
model.setChecked(true);
} else {
selectList.remove(s);
model.setChecked(false);
}
notifyItemChanged(getAdapterPosition());
}
});
public class Model {
private boolean isChecked = false;
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
}
Don't manually change the design in the onclick listener, just update your model (as you are already doing: model.setchecked(...) depending on state)
Then call Adapter.notifyItemChanged(getAdapterPosition())
This will force the adapter to reload the item, calling onBindViewHolder, where the design should be updated properly
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Model s = item.get(getAdapterPosition());
if (!selectList.contains(s)){
selectList.add(s);
model.setChecked(true);
} else {
selectList.remove(s);
model.setChecked(false);
}
adapter.notifyItemChanged(getAdapterPosition())
}
In the above example, replace "adapter" with a reference to your recylerview adapter
I have a single activity which replaces a fragment containing a recycler view with a fragment containing details of the selected viewholder item. When the back button is pressed the fragment containing the recycler view is restored but the recycler view items are no longer displayed. However, views are restored upon device rotation. All model data is stored in a SQLite database and the adapter list is updated on resume of its fragment .
CrimeListFragment.Java
public class CrimeListFragment extends Fragment {
private Callbacks callbacks;
public interface Callbacks {
public void onItemSelected(UUID id);
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
callbacks = (Callbacks) context;
}
#Override
public void onDetach() {
super.onDetach();
callbacks = null;
}
private RecyclerView crimeListRecycler;
private CrimeListAdapter adapter;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
crimeListRecycler = view.findViewById(R.id.crime_list);
crimeListRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_crime_list, menu);
MenuItem showSubtitle = menu.findItem(R.id.show_subtitle);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.new_crime:
Crime crime = new Crime();
CrimeLab.get(getActivity()).addCrime(crime);
/*Intent intent = CrimeActivity.createIntent(getActivity(), crime.getId());
startActivity(intent);*/
callbacks.onItemSelected(crime.getId());
return true;
default:
return onOptionsItemSelected(item);
}
}
private void updateUI() {
List<Crime> crimes = CrimeLab.get(getActivity()).getCrimes();
if (adapter == null) {
adapter = new CrimeListAdapter(crimes);
crimeListRecycler.setAdapter(adapter);
} else {
adapter.setCrimesList(crimes);
adapter.notifyDataSetChanged();
}
}
public class CrimeListAdapter extends RecyclerView.Adapter<CrimeListAdapter.CrimeHolder> {
private List<Crime> crimeList;
public CrimeListAdapter(List<Crime> crimes) {
crimeList = crimes;
}
#NonNull
#Override
public CrimeHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_crime, parent, false);
return new CrimeHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CrimeHolder holder, int position) {
Crime crime = crimeList.get(position);
holder.bind(crime);
}
#Override
public int getItemCount() {
return crimeList.size();
}
public void setCrimesList(List<Crime> crimes) {
crimeList = crimes;
}
public class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Crime crime;
private TextView crimeTitleTextView;
private TextView crimeDateTextView;
public CrimeHolder(#NonNull View itemView) {
super(itemView);
crimeTitleTextView = itemView.findViewById(R.id.crime_title);
crimeDateTextView = itemView.findViewById(R.id.crime_date);
itemView.setOnClickListener(this);
}
public void bind(Crime crime) {
this.crime = crime;
crimeTitleTextView.setText(crime.getTitle());
crimeDateTextView.setText(crime.getDate().toString());
}
#Override
public void onClick(View v) {
callbacks.onItemSelected(crime.getId());
/*Intent intent = CrimeActivity.createIntent(getActivity(), crime.getId());
startActivity(intent);*/
}
}
}
}
MasterActivity
public class MasterActivity extends AppCompatActivity implements CrimeListFragment.Callbacks {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new CrimeListFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
#Override
public void onItemSelected(UUID id) {
Fragment fragment = CrimeFragment.newInstance(id);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
}
Please share your code. Something to check when you replace/add your fragment on top of recyclerview fragment.
I want to start a dialogFragment on recycler view item click in RecyclerView Adapter
I tried
FragmentManager fr = ((Activity)context).getFragmentManager();
AnswersDialogFragment msgDialog = new AnswersDialogFragment();
msgDialog.show(fr, "Dialog");
but i get casting error
java.lang.ClassCastException: android.view.ContextThemeWrapper cannot be cast to android.support.v4.app.FragmentActivity
I want to start the dialog fragment on item click
#Override
public AnswersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.answercard, parent, false);
AnswersViewHolder evh = new AnswersViewHolder(v, mListener);
return evh;
}
#Override
public void onBindViewHolder(AnswersViewHolder holder, int position) {
int viewType = getItemViewType(position);
if(viewType==COMMENT_TYPE){
final Comments item = (Comments) commentsList.get(position);
holder.UserName.setText(Html.fromHtml(item.getUserName()));
holder.CommentText.setText(Html.fromHtml(item.getCommentText()));
}else{
final Replys replyitem = (Replys) commentsList.get(position);
holder.UserName.setText(Html.fromHtml(replyitem.getReplyAuthor()));
holder.CommentText.setText(Html.fromHtml(replyitem.getReplyBody()));
}
}
imgLikeComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fr = ((Activity)context).getFragmentManager();
AnswersDialogFragment msgDialog = new AnswersDialogFragment();
msgDialog.show(fr, "Dialog");
});
AnswersDialogFragment.java
public class AnswersDialogFragment extends DialogFragment {
ArrayList<Object> answersList;
RecyclerView recyclerView;
AnswersAdapter recyclerViewadapter;
RecyclerView.LayoutManager recyclerViewlayoutManager;
ImageView sendReply ;
EditText commentInput;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DialogStyle);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.nestedcomments, container, false);
..... etc
The Item click is working fine , i just can't start the fragment
try to use SupportFragmentManager instead
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
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.
I have a recyclerview with a textview and the clicked textview gets a background around it.I also have a button within the activity which should put a background to all the items in the recyclerview ie..to show all selected.I am putting my activity and adapter code.please help me
my activity code
set_all_days.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CommonUtility.selectedDays.clear();
CommonUtility.selectedDays.addAll(daysList);
//loadDays();
}
});
my adapter
public class DaysAdapter<T> extends RecyclerView.Adapter<DaysAdapter.ViewHolder> {
private ArrayList<String> list=new ArrayList<>();
private Context mContext;
private RecyclerViewClickListener mListener;
public DaysAdapter(ArrayList<String> data, Context context, RecyclerViewClickListener listener) {
list = data;
//languageListFiltered = filteredData;
mContext = context;
mListener = listener;
}
#Override
public void onBindViewHolder(DaysAdapter.ViewHolder viewHolder, final int position) {
viewHolder.titleTextView.setText(list.get(position));
// viewHolder.lang_radio.setChecked(position == mSelectedItem);
}
#Override
public int getItemCount() {
return list.size();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view = inflater.inflate(R.layout.days_list_item, viewGroup, false);
return new ViewHolder(view);
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView titleTextView;
public ViewHolder(final View inflate) {
super(inflate);
titleTextView = (TextView)inflate.findViewById(R.id.text_day);
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!CommonUtility.selectedDays.contains(titleTextView.getText().toString()))
{
titleTextView.setBackground(mContext.getResources().getDrawable(R.drawable.green_circle));
titleTextView.setTextColor(mContext.getResources().getColor(R.color.white));
CommonUtility.selectedDays.add(titleTextView.getText().toString());
Log.d("added",titleTextView.getText().toString());
}
else
{
int index=CommonUtility.selectedDays.indexOf(titleTextView.getText().toString());
CommonUtility.selectedDays.remove(index);
titleTextView.setBackground(null);
Log.d("removed",titleTextView.getText().toString());
titleTextView.setTextColor(mContext.getResources().getColor(R.color.black));
}
}
};
itemView.setOnClickListener(clickListener);
titleTextView.setOnClickListener(clickListener);
}
}
}