What I'm trying to do is to have a recycler view with a button in it. When the layout that has the recycler is initialized it will only have the button and once is clicked an item will be added(the first item) and the button(or imageview, whatever it has a + on it) pushed to the right. I have the recyclerView and it's working(by working I mean that I have some photos that are being displayed in the right order), but I can't get the button to display. I found various links sort of similar to this, such as How to add fixed Button in RecyclerView Adapter?, but I can't figure it out.
Here is the Adapter:
public class SelectPhotoAdapter extends
RecyclerView.Adapter<SelectPhotoHolder> {// Recyclerview will extend to
// recyclerview adapter
private ArrayList<Data_Model> arrayList;
private Context context;
private boolean hasLoadButton = true;
private final int IMAGES = 0;
private final int LOAD_MORE = 1;
public SelectPhotoAdapter (Context context,
ArrayList<Data_Model> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
public boolean isHasLoadButton() {
return hasLoadButton;
}
public void setHasLoadButton(boolean hasLoadButton) {
this.hasLoadButton = hasLoadButton;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
if (hasLoadButton) {
return arrayList.size() + 1;
} else {
return arrayList.size();
}
}
#Override
public int getItemViewType(int position) {
if (position < getItemCount()) {
return IMAGES;
} else {
return LOAD_MORE;
}
}
// #Override
// public int getItemCount() {
// return (null != arrayList ? arrayList.size() : 0);
//
// }
#Override
public void onBindViewHolder(SelectPhotoHolder holder, int position) {
SelectPhotoHolder mainHolder = holder;// holder
if(position >= getItemCount()) {
mainHolder.addPhoto.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//dostuff
}
});
} else {
final Data_Model model = arrayList.get(position);
Bitmap image = BitmapFactory.decodeResource(context.getResources(),
model.getImagePath());// This will convert drawbale image into
mainHolder.imageview.setImageBitmap(image);
}
}
#Override
public SelectPhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == IMAGES) {
return new SelectPhotoHolder((LayoutInflater.from(parent.getContext()).inflate(R.layout.selectphotolist, parent, false)),IMAGES);
} else if (viewType == LOAD_MORE) {
return new SelectPhotoHolder((LayoutInflater.from(parent.getContext()).inflate(R.layout.addphoto, parent, false)),LOAD_MORE);
} else {
return null;
}
}
}
If I use the getItemCount() which is commented I get the photos, but no button and if I use the uncommented getItemCount() which I took from the link provided it will crash. I also haven't figured out where to use isHasLoadButton() or setHasLoadButton methods. Could anyone point me in the right direction ?
If you need me to post anymore files let me know. Thank you.
The file which uses the recyclerView:
public class SelectPhotoDialogFragment extends DialogFragment {
private RecyclerView mRecyclerView;
private SelectPhotoAdapter adapter;
// this method create view for your Dialog
public static final Integer[] IMAGES= {R.drawable.first,R.drawable.second,R.drawable.third,R.drawable.picc};
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// request a window without the title
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate layout with recycler view
View v = inflater.inflate(R.layout.select_photo, container, false);
mRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
int recyclerHeight = mRecyclerView.getHeight();
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
ArrayList<Data_Model> arrayList = new ArrayList<>();
for (int i = 0; i < IMAGES.length; i++) {
arrayList.add(new Data_Model(IMAGES[i]));
}
adapter = new SelectPhotoAdapter(getActivity(), arrayList);
mRecyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.notifyDataSetChanged();// Notify the adapter
return v;
}
}
To explain again: The only thing that I'm seeing are the images(first,second,third,picc) and no button after, but they are displayed correctly. What I would like to happen is to have only the button as an item, and when I click on it to have a picture inserted before and it moving to the right(as you can see I have a horizontal orientation). This is what I've been trying to do with 2 ViewTypes, but I haven't figured it out.
The Holder:
public class SelectPhotoHolder extends RecyclerView.ViewHolder {
// View holder for gridview recycler view as we used in listview
private final int IMAGES = 0;
private final int LOAD_MORE = 1;
public ImageView imageview;
public Button addPhoto;
public SelectPhotoHolder(View view,int ViewType) {
super(view);
// Find all views ids
if(ViewType == IMAGES) {
this.imageview = (ImageView) view
.findViewById(R.id.selectPhoto);
}
else
this.addPhoto = (Button) view.findViewById(R.id.load_more);
}
}
new Holder output:
01-31 14:12:47.131 24072-24072/name.company.newapp E/test-exist: IMAGESfalse
01-31 14:12:47.141 24072-24072/name.company.newapp E/test-exist: IMAGESfalse
01-31 14:12:47.141 24072-24072/name.company.newapp E/test-exist: IMAGESfalse
01-31 14:12:47.151 24072-24072/name.company.newapp E/test-exist: IMAGESfalse
01-31 14:12:47.231 24072-24072/name.company.newapp E/test-exist: IMAGESfalse
#Override
public int getItemViewType(int position) {
if (position < getItemCount()-1) {
return IMAGES;
} else {
return LOAD_MORE;
}
}
public SelectPhotoHolder(View view,int ViewType) {
super(view);
// Find all views ids
if(ViewType == IMAGES) {
this.imageview = (ImageView) view
.findViewById(R.id.selectPhoto);
Log.e("test-exist", "IMAGES" + (imageview == null));
}else{
this.addPhoto = (Button) view.findViewById(R.id.load_more);
Log.e("test-exist", "LOAD_MORE" + (addPhoto == null));
}
}
#Override
public int getItemCount() {
if (hasLoadButton) {
return arrayList==null? 1 :arrayList.size() + 1;
} else {
return arrayList==null? 0 :arrayList.size();
}
}
if(position >= (arrayList==null? 0 :arrayList.size())) {
try{
mainHolder.addPhoto.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//dostuff
}
});
}catch(Throwable e){
Log.e("test-erorr","current position:"+position);
}
} else {
final Data_Model model = arrayList.get(position);
Bitmap image = BitmapFactory.decodeResource(context.getResources(),
model.getImagePath());// This will convert drawbale image into
mainHolder.imageview.setImageBitmap(image);
}
Here's a sample, that's why i meant in " sample - example ", modify it to your own requirements, This "sample" display Recyclerview items with images, below the recyclerview there's a button, when pressed it adds a new image, you can modify the place - animation, Here's the Item.java :
public class Item {
private int Pic;
public Item(String Title, int Pic, int Color) {
setPic(Pic);
}
public int getPic() {
return Pic;
}
public void setPic(int photo) {
this.Pic= photo;
}
}
Adapter :
public class Adapter extends RecyclerView.Adapter<RecyclerViewHolders>{
private List<Item> itemList;
public Context context;
public Adapter(Context context, List<Item> itemList) {
this.itemList = itemList;
this.context = context;
}
#Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.your_item, null);
return new RecyclerViewHolders(layoutView);
}
#Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
holder.Pic.setImageResource(itemList.get(position).getPic());
}
#Override
public int getItemCount() {
return this.itemList.size();
}
}
It's all normal to now, in your MainActivity or where your Adapter initialized
Adapter rcAdapter;
public static List<Item> Items;
public static Button button;
In your onCreate:
initListViews();
Now the initListViews method :
public void initListViews()
{
List<Item> rowListItem = getAllItemList();
LinearLayoutManager yourlayout= new LinearLayoutManager(this);
RecyclerView RcView = (RecyclerView)findViewById(R.id.recycler_view);
button = (Button)findViewById(R.id.button);
RcView.setHasFixedSize(true);
RcView.setLayoutManager(yourlayout);
rcAdapter = new RecyclerViewAdapter(this, rowListItem);
RcView.setAdapter(rcAdapter);
}
private List<Item> getAllItemList(){
Items.add(new Item(YourImageResources));
Items.add(new Item(YourImageResources));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AllItems.add(new Item(YourImageResources));
}
});
}
If you want a specific number of items to be added :
int PressedTimes = 0;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(PressedTimes < 7)
{
AllItems.add(new Item(YourImageResources));
PressedTimes=+1;
}
if(PressedTimes == 7)
{
button.setVisibility(View.GONE);
}
}
});
Related
In my application I want to drag list item. In my list item I have text view and image. So for that I followed the bellow url
https://github.com/woxblom/DragListView
By using this sample, I changed my text view and image view then displayed my data. And drag and drop also working fine. But the issue is image will not change. But the image is moving along with text. So my point is after dropping the item text is changed image wont changed. So how to change image also.
This is the my activity:
public class MainActivity extends AppCompatActivity {
private DragListView mDragListView;
private ArrayList<Pair<Long, String>> mItemArray;
private ArrayList arrayList_data = new ArrayList();
private ArrayList arrayList_images = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayList_data.add("Dashboard");
arrayList_data.add("Evaluations");
arrayList_data.add("Inventory");
arrayList_data.add("Buy Leads");
arrayList_data.add("Insurance");
arrayList_data.add("Cartrade Price");
arrayList_data.add("RTO Check");
arrayList_data.add("Market Place");
arrayList_data.add("Auctions");
arrayList_data.add("Integrator Report");
arrayList_data.add("What's New");
arrayList_images.add(R.mipmap.menu_dashboard);
arrayList_images.add(R.mipmap.menu_evaluations);
arrayList_images.add(R.mipmap.menu_inventory);
arrayList_images.add(R.mipmap.menu_buyleads);
arrayList_images.add(R.mipmap.menu_insurance);
arrayList_images.add(R.mipmap.menu_cartradeprice);
arrayList_images.add(R.mipmap.menu_rtocheck);
arrayList_images.add(R.mipmap.menu_marketplace);
arrayList_images.add(R.mipmap.menu_acuttions);
arrayList_images.add(R.mipmap.menu_integrator);
arrayList_images.add(R.mipmap.whatsnew);
mDragListView = (DragListView) findViewById(R.id.drag_list_view);
mDragListView.setDragListListener(new DragListView.DragListListenerAdapter() {
#Override
public void onItemDragStarted(int position) {
// mRefreshLayout.setEnabled(false);
Toast.makeText(mDragListView.getContext(), "Start - position: " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onItemDragEnded(int fromPosition, int toPosition) {
// mRefreshLayout.setEnabled(true);
if (fromPosition != toPosition) {
Toast.makeText(mDragListView.getContext(), "End - position: " + toPosition, Toast.LENGTH_SHORT).show();
}
}
});
mItemArray = new ArrayList<>();
for (int i = 0; i < arrayList_data.size(); i++) {
mItemArray.add(new Pair<>((long) i, arrayList_data.get(i).toString()));
}
// setupListRecyclerView();
setupGridVerticalRecyclerView();
}
private void setupListRecyclerView() {
mDragListView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
ItemAdapter listAdapter = new ItemAdapter(mItemArray, arrayList_images, R.layout.list_item, R.id.image, false);
mDragListView.setAdapter(listAdapter, true);
mDragListView.setCanDragHorizontally(false);
mDragListView.setCustomDragItem(new MyDragItem(MainActivity.this, R.layout.list_item));
}
private void setupGridVerticalRecyclerView() {
mDragListView.setLayoutManager(new GridLayoutManager(MainActivity.this, 3));
ItemAdapter listAdapter = new ItemAdapter(mItemArray, arrayList_images, R.layout.grid_item, R.id.item_layout, true);
mDragListView.setAdapter(listAdapter, true);
mDragListView.setCanDragHorizontally(true);
mDragListView.setCustomDragItem(null);
}
private static class MyDragItem extends DragItem {
MyDragItem(Context context, int layoutId) {
super(context, layoutId);
}
#Override
public void onBindDragView(View clickedView, View dragView) {
CharSequence text = ((TextView) clickedView.findViewById(R.id.text)).getText();
((TextView) dragView.findViewById(R.id.text)).setText(text);
ImageView image = ((ImageView) clickedView.findViewById(R.id.image));
((ImageView) dragView.findViewById(R.id.image)).setImageDrawable(image.getDrawable());
dragView.findViewById(R.id.item_layout).setBackgroundColor(dragView.getResources().getColor(R.color.list_item_background));
}
}
}
This is adapter class
class ItemAdapter extends DragItemAdapter<Pair<Long, String>, ItemAdapter.ViewHolder> {
private int mLayoutId;
private int mGrabHandleId;
private boolean mDragOnLongPress;
ArrayList<Integer> arl_images;
ItemAdapter(ArrayList<Pair<Long, String>> list, ArrayList<Integer> arl_images, int layoutId, int grabHandleId, boolean dragOnLongPress) {
mLayoutId = layoutId;
mGrabHandleId = grabHandleId;
mDragOnLongPress = dragOnLongPress;
setHasStableIds(true);
setItemList(list,arl_images);
this.arl_images = arl_images;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
String text = mItemList.get(position).second;
holder.mText.setText(text);
holder.image.setImageResource(arl_images.get(position));
holder.itemView.setTag(mItemList.get(position));
}
#Override
public long getItemId(int position) {
return mItemList.get(position).first;
}
class ViewHolder extends DragItemAdapter.ViewHolder {
TextView mText;
ImageView image;
ViewHolder(final View itemView) {
super(itemView, mGrabHandleId, mDragOnLongPress);
mText = (TextView) itemView.findViewById(R.id.text);
image = (ImageView) itemView.findViewById(R.id.image);
}
#Override
public void onItemClicked(View view) {
Toast.makeText(view.getContext(), "Item clicked", Toast.LENGTH_SHORT).show();
}
#Override
public boolean onItemLongClicked(View view) {
Toast.makeText(view.getContext(), "Item long clicked", Toast.LENGTH_SHORT).show();
return true;
}
}
}
Update function public void swapItems(int pos1, int pos2)in DragItemAdapter.java with arl_images list swap code.
public void swapItems(int pos1, int pos2) {
......
Collections.swap(mItemList, pos1, pos2);
Collections.swap(mArl_imagesList, pos1, pos2);
notifyDataSetChanged();
......
}
update ItemAdapter.java too
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
String text = mItemList.get(position);
holder.mText.setText(text);
holder.image.setImageResource(mArl_imagesList.get(position).second);//mArl_imagesList from DragItemAdapter
holder.itemView.setTag(mItemList.get(position));
}
You can use draglistview library :
https://android-arsenal.com/details/1/4036
I am implementing sticky header with RecyclerView. I have three sections (i.e 3 sticky headers) and they are working fine.Now I have taken three arraylists inside each section, I have initialized these list in my adapter and I am trying to get data of these lists on basis of header id inside onBindViewHolder. But it is not giving me the full list,just one string from each list (i.e under first section--data on first position of mylist,,,under second section-- data on second position of mylist1 ---under third section-- data on third position of mylist2)
Please Help !!
Code in Context:
StickyTestAdapter
public class StickyTestAdapter extends RecyclerView.Adapter<StickyTestAdapter.ViewHolder> implements
StickyHeaderAdapter<StickyTestAdapter.HeaderHolder> {
private Context mContext;
private ArrayList<String> mylist;
private ArrayList<String> mylist1;
private ArrayList<String> mylist2;
private static int countposition;
private String HEADER_FIRIST="HEADER_FIRIST";
private String HEADER_SECOND="HEADER_SECOND";
private String HEADER_THIRD="HEADER_THIRD";
public StickyTestAdapter(Context context) {
prepareData();
prepareData1();
prepareData2();
this.mContext=context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.item_test, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
long rowType= getHeaderId(position);
Log.e("getHeaderId----",""+rowType);
if (rowType==0){
if(!mylist.equals(""))
{
Log.e("list_data----", "" + mylist.get(position));
viewHolder.item.setText(mylist.get(position));
}
else
{
Log.e("Error--0--", "" + "error");
}
} else if (rowType==1){
if(!mylist1.equals(""))
{
Log.e("list_data1----", "" + mylist1.get(position));
viewHolder.item.setText(mylist1.get(position));
}
else
{
Log.e("Error---1-", "" + "error");
}
} else if (rowType==2){
if(!mylist2.equals(""))
{
Log.e("list_data2----", "" + mylist2.get(position));
viewHolder.item.setText(mylist2.get(position));
}
else
{
Log.e("Error----2", "" + "error");
}
}
}
#Override
public int getItemCount() {
if (getHeaderId(countposition)==0){
Log.e("mylist",""+mylist.size());
return mylist.size();
}else if (getHeaderId(countposition)==1){
Log.e("mylist1",""+mylist1.size());
return mylist1.size();
}else if (getHeaderId(countposition)==2){
Log.e("mylist2",""+mylist2.size());
return mylist2.size();
}
return 0;
}
#Override
public long getHeaderId(int pos) {
return pos;
}
#Override
public HeaderHolder onCreateHeaderViewHolder(ViewGroup parent) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.header_test, parent, false);
return new HeaderHolder(view);
}
#Override
public void onBindHeaderViewHolder(HeaderHolder viewholder, int count) {
countposition=count;
if (getItemViewType(count)==0){
viewholder.headertext.setText(HEADER_FIRIST);
}else if (getItemViewType(count)==1){
viewholder.headertext.setText(HEADER_SECOND);
}else if (getItemViewType(count)==2){
viewholder.headertext.setText(HEADER_THIRD);
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
public TextView item;
public ViewHolder(View itemView) {
super(itemView);
item = (TextView)itemView.findViewById(R.id.text_item);
}
}
static class HeaderHolder extends RecyclerView.ViewHolder {
public TextView headertext;
public HeaderHolder(View itemView) {
super(itemView);
headertext = (TextView)itemView.findViewById(R.id.header_text);
}
}
#Override
public int getItemViewType(int position) {
return position;
}
public void prepareData()
{
mylist=new ArrayList<>();
mylist.add("rajendra");
mylist.add("rani");
mylist.add("rahul");
}
public void prepareData1()
{
mylist1=new ArrayList<>();
mylist1.add("ravi");
mylist1.add("vikram");
mylist1.add("rakesh");
}
public void prepareData2()
{
mylist2=new ArrayList<>();
mylist2.add("apple");
mylist2.add("ashok");
mylist2.add("vikash");
}
}
Question is quite old. But that code looks complicated to read, personally I try to not reinvent what others did quite well by creating libraries.
GitHub is full of source that you can import. Some examples: FlexibleAdapter, FastAdapter, Epoxy and others.
I have build the first one, but you can try the others as well.
With mine, having multiple views and headers with sections is quite easy, I point here the wiki page where I define the section and how to initialize it.
Along with this feature, you have a lot more functionalities that makes your life easier.
I divide arraylist into 3 section based on alphabet like contactlist.
For that i use SectionedRecyclerViewAdapter
MainActivity.java
public class MainActivity extends AppCompactActivity {
private SectionedRecyclerViewAdapter sectionAdapter;
#Override
public View onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
sectionAdapter = new SectionedRecyclerViewAdapter();
for(char alphabet = 'a'; alphabet <= 'z';alphabet++) {
List<String> contacts = getContactsWithLetter(alphabet);
if (contacts.size() > 0) {
sectionAdapter.addSection(new ContactsSection(String.valueOf(alphabet), contacts));
}
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);
return view;
}
#Override
public void onResume() {
super.onResume();
if (getActivity() instanceof AppCompatActivity) {
AppCompatActivity activity = ((AppCompatActivity) getActivity());
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setTitle(R.string.nav_example1);
}
}
private List<String> getContactsWithLetter(char letter) {
List<String> contacts = new ArrayList<>();
for (String contact : getResources().getStringArray(R.array.names_)) {
if (contact.charAt(0) == letter) {
contacts.add(contact);
}
}
return contacts;
}
private class ContactsSection extends StatelessSection {
String title;
List<String> list;
ContactsSection(String title, List<String> list) {
super(new SectionParameters.Builder(R.layout.section_ex1_item)
.headerResourceId(R.layout.section_ex1_header)
.build());
this.title = title;
this.list = list;
}
#Override
public int getContentItemsTotal() {
return list.size();
}
#Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
return new ItemViewHolder(view);
}
#Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
final ItemViewHolder itemHolder = (ItemViewHolder) holder;
String name = list.get(position);
itemHolder.tvItem.setText(name);
itemHolder.imgItem.setImageResource(name.hashCode() % 2 == 0 ? R.drawable.ic_face_black_48dp : R.drawable.ic_tag_faces_black_48dp);
itemHolder.rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), String.format("Clicked on position #%s of Section %s", sectionAdapter.getPositionInSection(itemHolder.getAdapterPosition()), title), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new HeaderViewHolder(view);
}
#Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
headerHolder.tvTitle.setText(title);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
private final TextView tvTitle;
HeaderViewHolder(View view) {
super(view);
tvTitle = (TextView) view.findViewById(R.id.tvTitle);
}
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
private final View rootView;
private final ImageView imgItem;
private final TextView tvItem;
ItemViewHolder(View view) {
super(view);
rootView = view;
imgItem = (ImageView) view.findViewById(R.id.imgItem);
tvItem = (TextView) view.findViewById(R.id.tvItem);
}
}
}
use structure similar to
public class MultiArray<T> {
List<ItemGroup> lists = new ArrayList<>();
public void addList(String headerText, List<T> list) {
lists.add(new ItemGroup(headerText, list));
}
public int itemCount() {
int count = 0;
for (ItemGroup group : lists) {
count += group.count();
}
return count;
}
public T getItem(int position) {
int count = 0;
for (ItemGroup group : lists) {
if (count + group.count() >= position) {
return group.item(position - count);
}
count += group.count();
}
return null;
}
public int getGroupIndex(int position) {
int count = 0;
int groupIndex = 0;
for (ItemGroup group : lists) {
if (count + group.count() >= position) {
return groupIndex;
}
count += group.count();
groupIndex++;
}
return -1;
}
public String getHeaderText(int position){
int count = 0;
for (ItemGroup group : lists) {
if (count + group.count() >= position) {
return group.headerText;
}
count += group.count();
}
return "";
}
class ItemGroup {
public final String headerText;
public final List<T> list;
public ItemGroup(String headerText, List<T> list) {
this.headerText = headerText;
this.list = list;
}
public int count() {
return list.size();
}
public T item(int position) {
return list.get(position);
}
}
}
you can optimize it for faster performance
I have a recyclerView with 2 ViewTypes: Images and 1 button. When I click that button I'm able to add one more image each time. I want that when I have 5 images, the button to disappear, without using setView(Gone). Here is my adapter, and I'm trying to remove the button in onBindViewHolder:
public class SelectPhotoAdapter extends
RecyclerView.Adapter<SelectPhotoHolder> {// Recyclerview will extend to
// recyclerview adapter
private ArrayList<Data_Model> arrayList;
private Context context;
private boolean hasLoadButton = true;
private final int IMAGES = 0;
private final int LOAD_MORE = 1;
public SelectPhotoAdapter (Context context,
ArrayList<Data_Model> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
public boolean itHasLoadButton() {
return hasLoadButton;
}
public void setHasLoadButton(boolean hasLoadButton) {
this.hasLoadButton = hasLoadButton;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
if (hasLoadButton) {
return arrayList==null? 1 :arrayList.size() + 1;
} else {
return arrayList==null? 0 :arrayList.size();
}
}
#Override
public int getItemViewType(int position) {
if (position < getItemCount()-1) {
return IMAGES;
} else {
return LOAD_MORE;
}
}
#Override
public void onBindViewHolder(SelectPhotoHolder holder, int position) {
SelectPhotoHolder mainHolder = holder;// holder
if(position >= getItemCount() -1) {
mainHolder.addPhoto.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
arrayList.add(new Data_Model(SelectPhotoDialogFragment.IMAGES[0]));
SelectPhotoDialogFragment.adapter.notifyItemInserted(arrayList.size());
SelectPhotoDialogFragment.mRecyclerView.scrollToPosition(arrayList.size());
Log.d("askj","Sizee: "+arrayList.size());
if(arrayList.size()>5&&itHasLoadButton()){
setHasLoadButton(false);
SelectPhotoDialogFragment.adapter.notifyItemRemoved(arrayList.size() + 1);
SelectPhotoDialogFragment.adapter.notifyItemRangeChanged(arrayList.size() + 1, getItemCount());
Log.e("askj", "calledLoad");
}
}
});
} else {
final Data_Model model = arrayList.get(position);
Bitmap image = BitmapFactory.decodeResource(context.getResources(),
model.getImagePath());// This will convert drawbale image into
mainHolder.imageview.setImageBitmap(image);
}
}
#Override
public SelectPhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == IMAGES) {
return new SelectPhotoHolder((LayoutInflater.from(parent.getContext()).inflate(R.layout.selectphotolist, parent, false)),IMAGES);
} else if (viewType == LOAD_MORE) {
return new SelectPhotoHolder((LayoutInflater.from(parent.getContext()).inflate(R.layout.addphoto, parent, false)),LOAD_MORE);
} else {
return null;
}
}
}
The method is called(I can see in the console 'calledLoad'), but the button is still there. I thought that by calling setHasLoadButton(false) the button will disappear, but it's not happening.
Let me know if I have to add more code.
You can change condition in getItemViewType from position < getItemCount()-1 to arrayList!=null && position < arrayList.size().
Better also to move management of OnClickListener interface directly into ViewHolder.
I have a Recyclerview with header view as slider images and remaining view as normal recycler items.I am wondering if there is any way around to make the header view invisible depending upon some sort of condition.The recycler view consists of two separate layout files for this purpose: layout1 for header items and layout2 for normal recycler items and adapter will pick a layout and binds corresponding data at runtime.
This is my RecyclerView adapter RestaurantAdapter.java
public class RestaurantAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = RestaurantAdapter.class.getName();
private List<Restaurant> mList;
private Context mContext;
private RestaurantType mRestaurantType;
private static final int RECYCLER_HEADER=0,RECYCLER_ITEMS=1;
private LayoutInflater inflater;
private SlideItemViewHolder slideItemViewHolder;
private List<ImageSliderPOJO> mData;
public RestaurantAdapter(Context context, List<Restaurant> list, RestaurantType restaurantType) {
this.mContext = context;
this.mList = list;
this.mRestaurantType = restaurantType;
inflater=LayoutInflater.from(context);
}
public void updateAdapter(List<ImageSliderPOJO> data){
this.mData = data;
this.notifyDataSetChanged();
}
#Override
public int getItemCount() {
return mList.size();
}
#Override
public int getItemViewType(int position) {
return position == 0 ? RECYCLER_HEADER : RECYCLER_ITEMS;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int i) {
int viewType=viewHolder.getItemViewType();
switch (viewType){
case RECYCLER_HEADER:
slideItemViewHolder = (SlideItemViewHolder) viewHolder;
slideItemViewHolder.updateHeader();
break;
case RECYCLER_ITEMS:
final RecyclerItemViewHolder holder = (RecyclerItemViewHolder) viewHolder;
final Restaurant restaurant = mList.get(i);
Picasso.with(mContext)
.load(restaurant.getVendorLogo())
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(holder.restaurentImageView);
holder.restaurentNameTextView.setText(restaurant.getName());
//Remaining code here
break;
default:
throw new RuntimeException(TAG+":Unable to bind the viewType"+viewType);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType){
case RECYCLER_HEADER:
return new SlideItemViewHolder(inflater.inflate(R.layout.slide_show_restaurant_fragment_list,viewGroup,false));
case RECYCLER_ITEMS:
return new RecyclerItemViewHolder(inflater.inflate(R.layout.new_restautant_list_items, viewGroup, false));
default:
throw new RuntimeException(TAG+":Invalid ViewType "+viewType);
}
}
public static class RecyclerItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ClickListener clickListener;
//Initialization here.
public RecyclerItemViewHolder(View v) {
super(v);
ButterKnife.inject(this, v);
v.setOnClickListener(this);
}
#Override
public void onClick(View v) {
clickListener.onClick(v, getPosition(), false);
}
public interface ClickListener {
/**
* Called when the view is clicked.
*
* #param v view that is clicked
* #param position of the clicked item
* #param isLongClick true if long click, false otherwise
*/
public void onClick(View v, int position, boolean isLongClick);
}
/* Setter for listener. */
public void setClickListener(ClickListener clickListener) {
this.clickListener = clickListener;
}
}
// id = 87,170
private class SlideItemViewHolder extends RecyclerView.ViewHolder {
SliderLayout sliderLayout;
LinearLayout rootLinearLayout;
public SlideItemViewHolder(View recyclerHeader) {
super(recyclerHeader);
sliderLayout = (SliderLayout) recyclerHeader.findViewById(R.id.home_slider);
rootLinearLayout = (LinearLayout) recyclerHeader.findViewById(R.id.rootLinearLayout);
}
private void updateHeader() {
if(Util.isNetworkAvailable(mContext)){
for (int i = 0; i < mData.size(); i++) {
DefaultSliderView defaultSliderView = new DefaultSliderView(mContext);
final int finalI = i;
defaultSliderView.image(mData.get(finalI).getImageUrl())
.setOnSliderClickListener(new BaseSliderView.OnSliderClickListener() {
#Override
public void onSliderClick(BaseSliderView slider) {
Restaurant restaurantById = Restaurant.searchByRestaurantId(mData.get(finalI).getTargetVendorId());
if(restaurantById != null)
openDetailFragment(restaurantById);
}
});
sliderLayout.addSlider(defaultSliderView);
}
}
}
}
public void openDetailFragment(Restaurant restaurant) {
Intent intent = new Intent(mContext, DetailTabActivity.class);
intent.putExtra(DetailTabActivity.INTENT_RESTAURANT_DATA, restaurant);
mContext.startActivity(intent);
}
public SliderLayout getSliderLayout(){
return slideItemViewHolder.sliderLayout;
}
}
And this adapter is set and updated from this fragment RestaurantFragment.java as:
private void setAdapter() {
dismissDialog();
if (getActivity() != null)
getActivity().runOnUiThread(new Runnable(){
#Override
public void run() {
if (restaurantList != null && restaurantList.size() > 0) {
restaurantRecyclerView.setVisibility(View.VISIBLE);
mEmptyListTextView.setVisibility(View.GONE);
restaurentListAdapter = new RestaurantAdapter(getActivity(), restaurantList, mRestaurantType);
restaurantRecyclerView.setAdapter(restaurentListAdapter);
restaurentListAdapter.updateAdapter(mData);
restaurantRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int current_page) {
mCurrentPage = mCurrentPage + 1;
getHttpResturantData();
}
});
}
}
});
}
Is this much of an explanation helpful or should I paste more code?
Based on your code, it's possible to remove the header based on a certain condition.
Adjust your code to cater for the following:
#Override
public int getItemViewType(int position) {
if(hasHeaeder()) { // where you add the header
return position == 0 ? RECYCLER_HEADER : RECYCLER_ITEMS;
} else { // where you don't add the header
return RECYCLER_ITEMS;
}
}
This code also needs changing (currently it's wrong since it doesn't take care of the fact that the header adds 1 to the position).
final Restaurant restaurant = mList.get(i);
Replace it with
final Restaurant restaurant = hasHeader() ? mList.get(i +1) : mList.get(i);
Where hasHeader() is the code you need to write in order to determine whether or not the recycler should contain a header.
How can handle with this situation -> I have a list of itens in a recyclerView and I want to choose one of those option: green, yellow or red face to get the value of object from list item I chose
So I thought something like bellow, but when I select one of those faces anything happens. I think that button click listener doesn't work. Please someone can drive me to a better suggestion that works, give me an example or could me tell what am I doing wrong?
My adapter
public class LikeListAdapter extends RecyclerView.Adapter<LikeListAdapter.LikeItemViewHolder> {
private List<Goals> goalsList;
private SparseBooleanArray selectedItems;
public LikeListAdapter(List<Goals> goalsList) {
this.goalsList = goalsList;
}
#Override
public LikeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_item_like, parent, false);
return new LikeItemViewHolder(view);
}
#Override
public void onBindViewHolder(LikeItemViewHolder holder, int position) {
final Goals goals = goalsList.get(position);
if (goals != null && getItemCount() > 0) {
holder.goalsDescriptionTextView.setText(goals.getDescription());
holder.happyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("fretgr", "get Green Point = " + goals.getGreenPoint());
setToggleSelection(1);
}
});
holder.sosoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("rtret", "get Yellow Point = " + goals.getYellowPoint());
setToggleSelection(2);
}
});
holder.angryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("ewwr", "get Red Point = " + goals.getRedPoint());
setToggleSelection(3);
}
});
}
}
#Override
public int getItemCount() {
return goalsList.size();
}
public class LikeItemViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.description_goalsTextView)
TextView goalsDescriptionTextView;
#Bind(R.id.happy)
ImageView happyButton;
#Bind(R.id.soso)
ImageView sosoButton;
#Bind(R.id.angry)
ImageView angryButton;
public LikeItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
// method to access in activity after updating selection
public List<Goals> getGoalsList() {
return goalsList;
}
public void setToggleSelection(int pointType){
selectedItems = new SparseBooleanArray();
if (selectedItems.get(pointType, false)) {
selectedItems.delete(pointType);
} else {
selectedItems.put(pointType, true);
}
notifyItemChanged(pointType);
}
public int getToggleSelection(){
return 0;
}
}
My Fragment
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
assocGoalsRecyclerView.setLayoutManager(layoutManager);
assocGoalsRecyclerView.setHasFixedSize(true);
likeListAdapter = new LikeListAdapter(associateList);
assocGoalsRecyclerView.setAdapter(likeListAdapter);
assocGoalsRecyclerView.addOnItemTouchListener(RecycleTouchListener);
private RecyclerView.OnItemTouchListener RecycleTouchListener = new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = assocGoalsRecyclerView.findChildViewUnder(e.getX(), e.getY());
if(child!=null && mGestureDetector.onTouchEvent(e)){
final int position = assocGoalsRecyclerView.getChildAdapterPosition(child);
final Goals goals = associateList.get(position);
final Categories c = categoriesList.get(position);
final int type = likeListAdapter.getToggleSelection();
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) { }
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { }
};
I found an answer based in another responses and sugestions!!! Android: handling clicks on image view inside recycler's view item using touch framework
In My Fragment
Snippet from fragment:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
assocGoalsRecyclerView.setLayoutManager(layoutManager);
// assocGoalsRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));
assocGoalsRecyclerView.setHasFixedSize(true);
likeListAdapter = new LikeListAdapter(associateList, onItemClickCallback);
assocGoalsRecyclerView.setAdapter(likeListAdapter);
public static class OnItemClickListener implements View.OnClickListener {
private int position;
private OnItemClickCallback onItemClickCallback;
public OnItemClickListener(int position, OnItemClickCallback onItemClickCallback) {
this.position = position;
this.onItemClickCallback = onItemClickCallback;
}
#Override
public void onClick(View view) {
onItemClickCallback.onItemClicked(view, position);
}
public interface OnItemClickCallback {
void onItemClicked(View view, int position);
}
}
private OnItemClickListener.OnItemClickCallback onItemClickCallback = new OnItemClickListener.OnItemClickCallback() {
#Override
public void onItemClicked(View view, int position) {
switch(view.getId()){
case R.id.happy:
Log.e("rtetre", "happy assessed and position is = " + position);
break;
case R.id.soso:
Log.e("rwere", "soso assessed and position is = " + position);
break;
case R.id.angry:
Log.e("dfrefgt", "angry assessed and position is = " + position);
break;
}
}
};
In My adapter
public class LikeListAdapter extends RecyclerView.Adapter<LikeListAdapter.LikeItemViewHolder> {
private List<Goals> goalsList;
private LikeFragment.OnItemClickListener.OnItemClickCallback onItemClickCallback;
public LikeListAdapter(List<Goals> goalsList, LikeFragment.OnItemClickListener.OnItemClickCallback onItemClickCallback) {
this.goalsList = goalsList;
this.onItemClickCallback = onItemClickCallback;
}
#Override
public LikeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_item_like, parent, false);
LikeItemViewHolder likeItemViewHolder = new LikeItemViewHolder(view);
return likeItemViewHolder;
}
#Override
public void onBindViewHolder(LikeItemViewHolder holder, int position) {
final Goals goals = goalsList.get(position);
if (goals != null && getItemCount() > 0) {
holder.goalsDescriptionTextView.setText(goals.getDescription());
holder.happyButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
holder.sosoButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
holder.angryButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
}
}
#Override
public int getItemCount() {
return goalsList.size();
}
public static class LikeItemViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.description_goalsTextView)
TextView goalsDescriptionTextView;
#Bind(R.id.happy)
ImageView happyButton;
#Bind(R.id.soso)
ImageView sosoButton;
#Bind(R.id.angry)
ImageView angryButton;
public LikeItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}