0

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
Community
  • 1
  • 1
Bogdan Daniel
  • 2,689
  • 11
  • 43
  • 76
  • Correct me if i'm wrong, You have a recyclerview, you need to put a button in each item, and when that item is pressed you need to display the image ? or add a new item ?. – Jaeger Jan 31 '16 at 02:09
  • @AboHani I have a recyclerView, I want a button like some sort of last item(footer) which when clicked will add another item to the recyclerView before its position and it will therefore move to the right(my orientation is horizontal) and I also want the recycler to start only with that button(or whatever it might be- a + sign). – Bogdan Daniel Jan 31 '16 at 02:11
  • Ok then, gonna provide a sample with the what you explained. – Jaeger Jan 31 '16 at 02:15
  • What do you mean by sample ? – Bogdan Daniel Jan 31 '16 at 02:15
  • Sample - example - answer, lol . – Jaeger Jan 31 '16 at 02:25
  • I don't really get what's so lol about this. `sample - a small amount of something that gives you information about the thing it was taken from` I've already provided a sample and the tutorial that I followed. I asked what files do you need. You have the adapter there. What else could be relevant to this ? The button is just xml, so is the recycler. The problem is inside the adapter and maybe Where I initialize it, thing that I will be posting now. – Bogdan Daniel Jan 31 '16 at 02:33

2 Answers2

0
@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);
    }
tiny sunlight
  • 6,231
  • 3
  • 21
  • 42
0

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);
            }

        }
    });
Jaeger
  • 1,646
  • 8
  • 27
  • 59
  • Thank you. I'll have a look and get back to you. – Bogdan Daniel Jan 31 '16 at 03:40
  • To explain it again with an example. You know the facebook app on android, when you want to post a photo you add it and you have the option to add another right underneath that photo. If you add another the button will go below that photo and so on. That's what I m trying to do. – Bogdan Daniel Jan 31 '16 at 03:43
  • I want the button to keep getting pushed to the right and having it as a footer in the recycler I thought that it would do the trick – Bogdan Daniel Jan 31 '16 at 03:44
  • I've written that already, make a layout xml with the recycleview and a button inside that recyclerview, and then set the place of that button on the right, I've tried it on my device, and it shows exactly as you requested, when you press the button a new item will be added and the button will be below that added item. – Jaeger Jan 31 '16 at 03:51
  • I don't want the button to be below, I want it to be pushed to the right. The width of the layout is 100% and for me to add a button after the layout would mean to make the width 90% and the button 10% and anyway that wouldn't create the wanted effect.. I still think that the ViewType approach is the right one if I could figure it out – Bogdan Daniel Jan 31 '16 at 04:02
  • Mate, it's just an example, when clicked you can set the place of the button to be on the right, you can also set animations on the moving. – Jaeger Jan 31 '16 at 04:04
  • I've tried to do this implementation, but you said in the comments that the button is inside the recycler's layout, but judging by your `initListVies()` they are in the same layout, which is not what I want,because as I said the recycler takes full width, I can't add the button to the right... – Bogdan Daniel Jan 31 '16 at 13:12
  • If I misunderstood you again, I'm sorry. If you want, please update your answer with a full working solution. – Bogdan Daniel Jan 31 '16 at 13:15