I want to add the Fast-Scroll-Feature (like in the Android contacts app or in Whatsapp contacts) to my RecyclerView?
I would also use a listview but I need Cards in my app on the same layout!
If implementing fast-scroll to Recyclerview is too difficult, using a ViewStub is also an option, or not?
My RecyclerViewAdapter:
public class SongRecyclerViewAdapter extends RecyclerView.Adapter<SongRecyclerViewAdapter.Holder> {
private Song[] sSongs;
public SongRecyclerViewAdapter(Song[] songs) {
sSongs = songs;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_songview, parent, false);
Holder holder = new Holder(view);
return holder;
}
#Override
public void onBindViewHolder(Holder holder, int position) {
//holder.imvSong.setImageResource(R.drawable.standardartwork);
holder.txvSongTitle.setText(sSongs[position].getTitle());
holder.txvSongInfo.setText(sSongs[position].getArtists());
}
#Override
public int getItemCount() {
return sSongs != null ? sSongs.length : 0;
}
public class Holder extends RecyclerView.ViewHolder {
LinearLayout linearLayout;
ImageView imvSong;
TextView txvSongTitle;
TextView txvSongInfo;
public Holder(View layout) {
super(layout);
linearLayout = (LinearLayout) layout;
imvSong = (ImageView) layout.findViewById(R.id.imvSong);
txvSongTitle = (TextView) layout.findViewById(R.id.adap_txvSongtitle);
txvSongInfo = (TextView) layout.findViewById(R.id.txvSongInfo);
}
}
}
Thanks!
the problem in your code would be the commented line :
//holder.imvSong.setImageResource(R.drawable.standardartwork);
to handle this you have 2 solutions:
1) if u have limited small amount of known images, you can to create bitmaps/drawables once when initializing then you will only need to reference those.
2) create a bitmap cache, smart way to decode bitmaps along with reusable bitmap pool and pooling mechanism. This is not trivial and this what 3rd party libraries do for you. I would not suggest to implemented it yourself.
Related
Actually i am new to android development and working on an app and trying to implement viewpager to show the images like carousel in recyclerview but don't know how to set the viewpager in recyclerview onBindViewHolder function to show viewpager the images.
Actually i m trying to implement like this
and this is mine app's screenshot
so please guide me how can i implement it
my Adapter Class
public class RoomsAdapter extends RecyclerView.Adapter<RoomsAdapter.RoomsViewHolder> {
Context context;
ArrayList<Rooms> rooms;
public RoomsAdapter(Context context, ArrayList<Rooms> rooms) {
this.context = context;
this.rooms = rooms;
}
#NonNull
#Override
public RoomsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_product, parent, false);
RoomsViewHolder viewHolder = new RoomsViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull RoomsViewHolder holder, int position) {
Rooms room = rooms.get(position);
holder.binding.roomsTitle.setText(room.getTitle());
holder.binding.roomsRent.setText("Rent ₹ " + room.getPrice() + " /month");
holder.binding.roomsLocation.setText(room.getLocation());
}
#Override
public int getItemCount() {
return rooms.size();
}
public class RoomsViewHolder extends RecyclerView.ViewHolder {
ItemProductBinding binding;
public RoomsViewHolder(#NonNull View itemView) {
super(itemView);
binding = ItemProductBinding.bind(itemView);
}
}
}
Actually, i didn't set the viewpager here coz i know how to the set the image view but not any idea how can I set the viewpager in recyclerview to show images from url or drawable.
Please guide me
I've noticed RecyclerView "recycle" the views in the adapter but i want stop RecyclerView adapter duplicate the checked action in another item of the RecyclerView.
I have 10 items drawed into a RecyclerView, each one of them have a RadioGroup with 2 RadioButton within, but when i fired the check in the first item, for example, the number ten item have a checked too.
I was reading this question but i could'nt got it work.
Using Radio button with recyclerview in android
How to avoid this?
My adapter:
...
public class PreguntaAdapter extends RecyclerView.Adapter<PreguntaAdapter.ViewHolder> {
private Context context;
private ArrayList<VistaEncuestaActivity.PreguntasSiNo> preguntas;
public ArrayList<Respuestas> respuestas = new ArrayList<Respuestas>();
public PreguntaAdapter(Context context, ArrayList<VistaEncuestaActivity.PreguntasSiNo> preguntas) {
this.context = context;
this.preguntas = preguntas;
}
public ArrayList<Respuestas> getCheckedItems() {
return respuestas;
}
#NonNull
#Override
public PreguntaAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
Context context = viewGroup.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
View v = layoutInflater.inflate(R.layout.item_pregunta_sino, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final PreguntaAdapter.ViewHolder viewHolder, int i) {
final VistaEncuestaActivity.PreguntasSiNo currentPregunta = preguntas.get(i);
//viewHolder.pregunta.setText(currentEncuesta.getString_pregunta());
viewHolder.pregunta.setText(currentPregunta.getQuestion());
viewHolder.myLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.setIsRecyclable(false);
}
#Override
public int getItemCount() {
return preguntas.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public SharedPreferences prefs;
private LinearLayout myLinearLayout;
public TextView pregunta;
public RadioGroup radio_group;
public ViewHolder(#NonNull View itemView) {
super(itemView);
pregunta = (TextView) itemView.findViewById(R.id.pregunta);
radio_group = (RadioGroup) itemView.findViewById(R.id.radio_group_pregunta);
prefs = (SharedPreferences) context.getSharedPreferences("logged", Context.MODE_PRIVATE);
myLinearLayout = (LinearLayout) itemView.findViewById(R.id.myLinearLayout);
}
}
}
Thanks all of you for your responses. Unfortunally any response helped me to solve this issue, i used this function and i added the getItemViewType function to my adapter and it's working well now:
#Override
public int getItemViewType(int position) {
return position;
}
And going to the official google docs i could find the next information:
Return the view type of the item at position for the purposes of view recycling. The default implementation of this method returns 0, making the assumption of a single view type for the adapter. Unlike ListView adapters, types need not be contiguous. Consider using id resources to uniquely identify item view types. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter
This make sense at the time RecyclerView "recycle" the views but when this is use it in the adapter this have a different behavior treating each view as unique.
Thank you to all of you.
RadioGroup.getCheckedRadioButtonId() is the way to go. In conjunction with a SparseArray<Integer>.
In onBindViewHolder():
On each RadioGroup, set a RadioGroup.OnCheckedChangeListener(). Add the checked state to the a SparseArray or Map<Integer,Integer> mapping the index of the item position to the updated value in RadioGroup.OnCheckedChangeListener() onCheckedChanged.
So your onBindViewHolder would look something like this:
private SparseArray<Integer> mMapping = new SparseArray<>();
public void onBindViewHolder(#NonNull final PreguntaAdapter.ViewHolder viewHolder,final int position) {
final VistaEncuestaActivity.PreguntasSiNo currentPregunta = preguntas.get(i);
//viewHolder.pregunta.setText(currentEncuesta.getString_pregunta());
viewHolder.pregunta.setText(currentPregunta.getQuestion());
viewHolder.myLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.radio_group.setOnCheckedChangeListener(new OnCheckedChangeListener(){
void onCheckedChanged(RadioGroup group,int checked) {
mMapping.put(position,checked);
}
}};
// Check to see if a previous checked value exists and restore.
if(mMapping.get(position) != null && mMapping.get(position) != -1){
radio_group.check(mMapping.get(position));
}
viewHolder.setIsRecyclable(false);
}
onCheckedChanged(RadioGroup group, int checkedId)
You should give each RadioButton a unique ID, like radioButton_1, radioButton_2 in your layout file.
How can I set two text blocks in the listView, of which the first is on the left, the other on the right? I am tried to create a new layout with two textViews. But I don't know how I can connect textViews with listView and how I can set texts on textViews. May anybody help me?
I would like to have a list like this
Assuming you have the list and your layout with those 2 textview is ready just use this adapter and set this adapter to recycler view of the activity. let me know if you face any issues
public class CountryCodeAdapter extends RecyclerView.Adapter<CountryCodeAdapter.ViewHolder> {
private CountryCodeActivity activity;
ArrayList<CountryCodeModel> list = new ArrayList<>();
int selected_pos = 0;
public CountryCodeAdapter(CountryCodeActivity activity, ArrayList<CountryCodeModel> list) {
this.activity = activity;
this.list = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_country_listing, parent, false);
return new ViewHolder(rootView);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.tv_row_CountryCodeActivity_countrycode.setText(list.get(holder.getAdapterPosition()).getDial());
holder.tv_row_CountryCodeActivity_countryname.setText(list.get(holder.getAdapterPosition()).getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("country_code", list.get(holder.getAdapterPosition()).getDial());
activity.setResult(activity.RESULT_OK, intent);
activity.finish();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_row_CountryCodeActivity_countryname,
tv_row_CountryCodeActivity_countrycode;
public ViewHolder(View itemView) {
super(itemView);
tv_row_CountryCodeActivity_countryname = itemView.findViewById(R.id.tv_row_CountryCodeActivity_countryname);
tv_row_CountryCodeActivity_countrycode = itemView.findViewById(R.id.tv_row_CountryCodeActivity_countrycode);
tv_row_CountryCodeActivity_countryname.setTypeface(AppClass.Lato_Regular);
tv_row_CountryCodeActivity_countrycode.setTypeface(AppClass.Lato_Regular);
}
}
}
1)You should use RecyclerView insteaad of listView, and for recyclerView you can achieve what you want with item decorator.
2)But if you have to use ListView(which is less possible case) you can do this by checking list item position and set the corresponding margin to the layout which is not recomended.
3)Also there is another way to achieve this, which is to use different layout resource xml files, but I would not use the last two variants. I would prefer the first.
Well i tried to implement the recyclerview into Android Studio like this :
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder> {
public String[] dataSet;
public Context context;
//---------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------//
public class ViewHolder extends RecyclerView.ViewHolder{
public ImageView image;
public TextView name;
public ViewHolder(View itemView) {
super(itemView);
this.image = itemView.findViewById(R.id.image);
this.name = itemView.findViewById(R.id.name);
}
public void bindData(Object data){
String extractedData = (String)data;
this.name.setText("");
this.name.setText(extractedData);
this.image.getLayoutParams().height = getRandomIntInRange(250, 100);
}
}
//---------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------//
public RecycleViewAdapter(Context context, String[] dataSet){
this.context = context;
this.dataSet = dataSet;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.food_view,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
// Resolves the messed up views after recycling.
viewHolder.setIsRecyclable(false);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.bindData(dataSet[position]);
}
#Override
public int getItemCount() {
return dataSet.length;
}
// Custom method to get a random number between a range
protected int getRandomIntInRange(int max, int min){
Random rdm = new Random();
return rdm.nextInt((max-min)+min)+min;
}
}
Somehow i noticed that once i scroll up and down the recycled views get messed up...
Heres a Picture without Scrolling :
normal
And here is one after Scrolling... as you can see totally messed up :
messed up
Why does this happen and how can i prevent this ?
Does anyone got a solution ?
Well
Adapter is calling onBindViewHolder() all times when he must recreate view on the screen. You need to call getRandomIntInRange() outside of onBindViewHolder()
You could see it:
I am trying to implement ViewHolder in my Android app, but I keep getting that ViewHolder cannot be resolved to a type, without any suggestions for an import. Anyone know how to get around this?
That's because a ViewHolder is not a class that is from the Android SDK, you make it yourself.
Based on what I can find, a ViewHolder is an implementation that stores Views (per row in a ListView usually) for a larger area, so it is a sort of helper class and cache mechanism. This is one example I found on Android Developers of what a ViewHolder would contain.
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
Then you can implement it in a ListAdapter or a similar class.
**Create a Holder class**
protected static class ViewHolderItems
{
private ImageView mStoreImage;
private TextView mStoreName;
}
And use In getView method of adapter
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItems viewHolder;
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.coupen_row, null);
viewHolder = new ViewHolderItems();
viewHolder.mStoreImage = (ImageView) convertView.findViewById(R.id.storeImage);
viewHolder.mStoreName = (TextView) convertView.findViewById(R.id.storeName);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolderItems) convertView.getTag();
}
return convertView;
}
Maybe you are looking for the RecyclerView.ViewHolder which is part of the android support lib.
Like the code from this link gist by Paul Burke
public static class ItemViewHolder extends RecyclerView.ViewHolder implements
ItemTouchHelperViewHolder {
public final TextView textView;
public final ImageView handleView;
public ItemViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text);
handleView = (ImageView) itemView.findViewById(R.id.handle);
}
#Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
#Override
public void onItemClear() {
itemView.setBackgroundColor(0);
}
}
This would make sense for you if you were working with an Android RecyclerView
In this case they need an object to hold the view so that it can be filled with content as needed.