4

I am working in a social networking application in which my requirement is to fetch images from gallery and show in Mosaic style. It is similar to Grid View but here the size of the different images differ from each other. I have attached an Image to show the demo screen. enter image description here

Please suggest me for this.

Sam-In-TechValens
  • 2,501
  • 4
  • 34
  • 67

2 Answers2

1

Thanks to Siddharth Lele for the Idea, so that I came to this solution. I am pasting the code which is structured. I got some problems while arranging it in a format, now i think others can have it with that tension. Just keep in mind that the code is just for 4.0 and above.

activity_main.xml

    <com.jake.quiltviewsample.QuiltView
        android:id="@+id/quilt"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dip" >
    </com.jake.quiltviewsample.QuiltView>

</FrameLayout>

MainActivity.java

public class MainActivity extends Activity {
    public QuiltView quiltView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        quiltView = (QuiltView) findViewById(R.id.quilt);
        quiltView.setChildPadding(5);
        addTestQuilts(200);
    }

    public void addTestQuilts(int num){
        ArrayList<ImageView> images = new ArrayList<ImageView>();
        for(int i = 0; i < num; i++){
            ImageView image = new ImageView(this.getApplicationContext());
            image.setScaleType(ScaleType.CENTER_CROP);
            if(i % 2 == 0)
                image.setImageResource(R.drawable.mayer);
            else 
                image.setImageResource(R.drawable.mayer1);
            images.add(image);
        }
        quiltView.addPatchImages(images);
    }

    }

QuiltView.java

public class QuiltView extends FrameLayout implements OnGlobalLayoutListener {

    public QuiltViewBase quilt;
    public ViewGroup scroll;
    public int padding = 5;
    public boolean isVertical = false;
    public ArrayList<View> views;
    private Adapter adapter;

    public QuiltView(Context context,boolean isVertical) {
        super(context);
        this.isVertical = isVertical;
        setup();
    }

    public QuiltView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.QuiltView);

        String orientation = a.getString(R.styleable.QuiltView_scrollOrientation);
        if(orientation != null){
            if(orientation.equals("vertical")){
                isVertical = true;
            } else {
                isVertical = false;
            }
        }
        setup();
    }

    public void setup(){
        views = new ArrayList<View>();

        if(isVertical){
            scroll = new ScrollView(this.getContext());
        } else {
            scroll = new HorizontalScrollView(this.getContext());
        }
        quilt = new QuiltViewBase(getContext(), isVertical);
        scroll.addView(quilt);
        this.addView(scroll);

    }

    private DataSetObserver adapterObserver = new DataSetObserver(){
        public void onChanged(){
            super.onChanged();
            onDataChanged();
        }

        public void onInvalidated(){
            super.onInvalidated();
            onDataChanged();
        }

        public void onDataChanged(){
            setViewsFromAdapter(adapter);
        }
    };

    public void setAdapter(Adapter adapter){
        this.adapter = adapter;
        adapter.registerDataSetObserver(adapterObserver);
        setViewsFromAdapter(adapter);
    }

    private void setViewsFromAdapter(Adapter adapter) {
        this.removeAllViews();
        for(int i = 0; i < adapter.getCount(); i++){
            quilt.addPatch(adapter.getView(i, null, quilt));
        }
    }

    public void addPatchImages(ArrayList<ImageView> images){

        for(ImageView image: images){
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
            image.setLayoutParams(params);

            LinearLayout wrapper = new LinearLayout(this.getContext());
            wrapper.setPadding(padding, padding, padding, padding);
            wrapper.addView(image);
            quilt.addPatch(wrapper);
        }
    }

    public void addPatchViews(ArrayList<View> views_a){
        for(View view: views_a){
            quilt.addPatch(view);
        }
    }

    public void addPatchesOnLayout(){
        for(View view: views){
            quilt.addPatch(view);
        }
    }

    public void removeQuilt(View view){
        quilt.removeView(view);
    }

    public void setChildPadding(int padding){
        this.padding = padding;
    }

    public void refresh(){
        quilt.refresh();
    }

    public void setOrientation(boolean isVertical){
        this.isVertical = isVertical;
    }


    @Override
    public void onGlobalLayout() {
        //addPatchesOnLayout();
        }
    }

**QuiltViewBase.java**

    public class QuiltViewBase extends GridLayout {

        public int[] size;
        public int columns;
        public int rows;
        public int view_width = -1;
        public int view_height = -1;
        public boolean isVertical = true;
        public ArrayList<View> views;

        public QuiltViewBase(Context context, boolean isVertical) {
            super(context);
            this.isVertical = isVertical;
            if(view_width == -1){
                DisplayMetrics metrics = this.getResources().getDisplayMetrics();
                int width = metrics.widthPixels;
                int height = metrics.heightPixels - 120;
                view_width = width - this.getPaddingLeft() - this.getPaddingRight();
                view_height = height - this.getPaddingTop() - this.getPaddingBottom();
            }
            views = new ArrayList<View>();
            setup();
        }

        public void setup(){
            if(isVertical){
                setupVertical();
            } else {
                setupHorizontal();
            }
        }

        public void setupVertical(){
            size = getBaseSizeVertical();
            this.setColumnCount(columns);
            this.setRowCount(-1);
            this.setOrientation(this.HORIZONTAL);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
            this.setLayoutParams(params);
        }

        public void setupHorizontal(){
            size = getBaseSizeHorizontal();
            this.setRowCount(rows);
            this.setColumnCount(-1);
            this.setOrientation(this.VERTICAL);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
            this.setLayoutParams(params);
        }

        public void addPatch(View view){

            int count = this.getChildCount();

            QuiltViewPatch child = QuiltViewPatch.init(count, columns);

            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.width = size[0]*child.width_ratio;
            params.height = size[1]*child.height_ratio;
            params.rowSpec = GridLayout.spec(Integer.MIN_VALUE, child.height_ratio);
            params.columnSpec = GridLayout.spec(Integer.MIN_VALUE, child.width_ratio);
            view.setLayoutParams(params);
            addView(view);
            views.add(view);
        }

        public void refresh(){
            this.removeAllViewsInLayout();
            setup();
            for(View view : views){
                addPatch(view);
            }
        }

        public int[] getBaseSize(){
            int[] size = new int[2];

            float width_height_ratio = (3.0f/4.0f);

            int base_width = getBaseWidth();
            int base_height = (int) (base_width*width_height_ratio);

            size[0] = base_width; // width
            size[1] = base_height; // height
            return size;
        }

        public int[] getBaseSizeVertical(){
            int[] size = new int[2];

            float width_height_ratio = (3.0f/4.0f);

            int base_width = getBaseWidth();
            int base_height = (int) (base_width*width_height_ratio);

            size[0] = base_width; // width
            size[1] = base_height; // height
            return size;
        }

        public int[] getBaseSizeHorizontal(){
            int[] size = new int[2];

            float width_height_ratio = (4.0f/3.0f);

            int base_height = getBaseHeight();
            int base_width = (int) (base_height*width_height_ratio);

            size[0] = base_width; // width
            size[1] = base_height; // height
            return size;
        }

        public int getBaseWidth(){
            if(view_width < 500){
                columns = 2;
            } else if(view_width < 801){
                columns = 3;
            } else if(view_width < 1201){
                columns = 4;
            } else if(view_width < 1601){
                columns = 5;
            } else {
                columns = 6;
            }
            return (view_width / columns);
        }

        public int getBaseHeight(){
            if(view_height < 350){
                rows = 2;
            } else if(view_height < 650){
                rows = 3;
            } else if(view_height < 1050){
                rows = 4;
            } else if(view_height < 1250){
                rows = 5;
            } else {
                rows = 6;
            }
            return (view_height / rows);
        }

         /*@Override 
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
            int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);

            view_width = parentWidth;
            view_height = parentHeight;

            setup(isVertical);
         }*/

        @Override
        protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
                super.onSizeChanged(xNew, yNew, xOld, yOld);
                view_width = xNew;
                view_height = yNew;
        }


    }

**QuiltViewPatch.java**


public class QuiltViewPatch implements Comparable{
    public int width_ratio;
    public int height_ratio;

    public QuiltViewPatch(int width_ratio, int height_ratio){
        this.width_ratio = width_ratio;
        this.height_ratio = height_ratio;
    }

    private static QuiltViewPatch create(Size size){
        switch(size){
        case Big:
            return new QuiltViewPatch(2,2);
        case Small:
            return new QuiltViewPatch(1,1);
        case Tall:
            return new QuiltViewPatch(1,2);
        }

        return new QuiltViewPatch(1,1);
    }

    public int getHeightRatio(){return this.height_ratio;}
    public int getWidthRatio(){return this.width_ratio;}

    public static QuiltViewPatch create(int view_count){

        if(view_count == 0)
            return new QuiltViewPatch(2,2);
        else if((view_count % 11) == 0)
            return new QuiltViewPatch(2,2);
        else if((view_count % 4) == 0)
            return new QuiltViewPatch(1,2);
        else 
            return new QuiltViewPatch(1,1);

    }

    private enum Size{
        Big,
        Small,
        Tall
    }

    public static QuiltViewPatch init(int position, int column){
        switch(column){
        case 2:
            return init2(position);
        case 3:
            return init3(position);
        case 4:
            return init4(position);
        case 5:
            return init5(position);
        }

        return init3(position);
    }

    private static QuiltViewPatch init2(int position){
        switch(position % 15){
        case 0:
            return create(Size.Big);
        case 1:
        case 2:
        case 3:
            return create(Size.Small);
        case 4:
            return create(Size.Tall);
        case 5:
        case 6:
        case 7:
            return create(Size.Small);
        case 8:
            return create(Size.Tall);
        case 9:
            return create(Size.Tall);
        case 10:
            return create(Size.Small);
        case 11:
            return create(Size.Big);
        case 12:
            return create(Size.Tall);
        case 13:
            return create(Size.Tall);
        case 14:
            return create(Size.Small);
        }

        return create(Size.Small);
    }

    private static QuiltViewPatch init3(int position){
        switch(position % 32){
        case 0:
            return create(Size.Big);
        case 1:
        case 2:
        case 3:
            return create(Size.Small);
        case 4:
            return create(Size.Tall);
        case 5:
        case 6:
        case 7:
            return create(Size.Small);
        case 8:
            return create(Size.Tall);
        case 9:
        case 10:
            return create(Size.Small);
        case 11:
            return create(Size.Big);
        case 12:
            return create(Size.Tall);
        case 13:
        case 14:
            return create(Size.Small);
        case 15:
            return create(Size.Small);
        case 16:
            return create(Size.Tall);
        case 17:
        case 18:
        case 19:
            return create(Size.Small);
        case 20:
            return create(Size.Tall);
        case 21:
        case 22:
            return create(Size.Small);
        case 23:
            return create(Size.Big);
        case 24:
            return create(Size.Small);
        case 25:
            return create(Size.Tall);
        case 26:
        case 27:
        case 28:
            return create(Size.Small);
        case 29:
            return create(Size.Tall);
        case 30:
        case 31:
            return create(Size.Small);
        }

        return create(Size.Small);
    }

    private static QuiltViewPatch init4(int position){
        switch(position % 36){
        case 0:
            return create(Size.Big);
        case 1:
        case 2:
        case 3:
            return create(Size.Small);
        case 4:
            return create(Size.Tall);
        case 5:
        case 6:
        case 7:
            return create(Size.Small);
        case 8:
            return create(Size.Tall);
        case 9:
        case 10:
        case 11:
            return create(Size.Small);
        case 12:
            return create(Size.Big);
        case 13:
            return create(Size.Tall);
        case 14:
        case 15:
        case 16:
            return create(Size.Small);
        case 17:
            return create(Size.Tall);
        case 18:
        case 19:
        case 20:
            return create(Size.Small);
        case 21:
            return create(Size.Tall);
        case 22:
        case 23:
            return create(Size.Small);
        case 24:
            return create(Size.Small);
        case 25:
            return create(Size.Big);
        case 26:
            return create(Size.Small);
        case 27:
            return create(Size.Tall);
        case 28:
        case 29:
        case 30:
            return create(Size.Small);
        case 31:
            return create(Size.Tall);
        case 32:
        case 33:
        case 34:
        case 35:
            return create(Size.Small);
        }

        return create(Size.Small);
    }

    private static QuiltViewPatch init5(int position){
        switch(position % 35){
        case 0:
            return create(Size.Big);
        case 1:
        case 2:
        case 3:
            return create(Size.Small);
        case 4:
            return create(Size.Tall);
        case 5:
        case 6:
        case 7:
            return create(Size.Small);
        case 8:
            return create(Size.Tall);
        case 9:
        case 10:
        case 11:
            return create(Size.Small);
        case 12:
            return create(Size.Big);
        case 13:
            return create(Size.Tall);
        case 14:
        case 15:
        case 16:
            return create(Size.Small);
        case 17:
            return create(Size.Tall);
        case 18:
        case 19:
        case 20:
            return create(Size.Small);
        case 21:
            return create(Size.Tall);
        case 22:
        case 23:
        case 24:
            return create(Size.Small);
        case 25:
            return create(Size.Big);
        case 26:
            return create(Size.Small);
        case 27:
            return create(Size.Tall);
        case 28:
        case 29:
        case 30:
            return create(Size.Small);
        case 31:
            return create(Size.Tall);
        case 32:
            return create(Size.Big);
        case 33:
            return create(Size.Tall);
        case 34:
            return create(Size.Small);

        }

        return create(Size.Small);
    }

    public static boolean getRandomBoolean(){
        return (Math.random() < 0.5);
    }

    public boolean equals(Object obj){
        if(obj != null && obj instanceof QuiltViewPatch){
            QuiltViewPatch size = (QuiltViewPatch)obj;
            return size.height_ratio == this.height_ratio && size.width_ratio == this.width_ratio;
        }

        return false;
    }

    public int hashCode(){
        return height_ratio + 100 * width_ratio;
    }

    public String toString(){
        return "Patch: " + height_ratio +  " x " + width_ratio;
    }

    @Override
    public int compareTo(Object another) {
        if(another != null && another instanceof QuiltViewPatch){
            QuiltViewPatch size = (QuiltViewPatch)another;
            if(size.equals(this))
                return 0;

            if(this.height_ratio < size.height_ratio)
                return -1;
            else if(this.height_ratio > size.height_ratio)
                return 1;

            if(this.width_ratio < size.width_ratio)
                return -1;
            else
                return 1;
        }
        return -1;
    }
}
Dharmendra
  • 33,296
  • 22
  • 86
  • 129
Sam-In-TechValens
  • 2,501
  • 4
  • 34
  • 67
  • 1
    How is it possible to change the size/position of a picture after it is added to the QuildView? – Naskov Nov 21 '13 at 10:08
  • Cause I am working on an application that requires that.. Is there any way to do that? – Naskov Nov 21 '13 at 12:49
  • I have not worked on this... but i think u can do that in anther screen. – Sam-In-TechValens Nov 21 '13 at 13:10
  • 1
    Can you help me.i got this Runtimeexception -android.view.InflateException: Binary XML file line #7: Error inflating class com.akanksha.mosaicexperiment.QuiltView. I have also added jar from here https://github.com/jacobmoncur/gridlayout_v7/tree/master/libs and my target is 4.0 – Akanksha Rathore Feb 17 '14 at 14:14
0

I was looking how to do this too, but found out that Google now have this covered with RecyclerView and StaggeredGridLayoutManager. I would suggest looking there first now.

Kumar Saurabh
  • 2,297
  • 5
  • 29
  • 43
Simon Featherstone
  • 1,716
  • 23
  • 40