Wednesday, 8 June 2016

Best way to display multiple image grid like facebook Part - 2

In the First part of the tutorial Best way to display multiple image grid like facebook Part - 1 we create the base structure for facebook grid,
Now we create the whole structure for making amazing facebook type grid




                            



Here In Part - 2 we create the child view for multiple Images
for that 

Step - 1:
Create a POJO(model) class which implements AsymmetricItem for manage custom view


package com.at.facebooktypeimagegrid.model;

import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;

import com.at.facebooktypeimagegrid.Assymetric.AsymmetricItem;


public class ItemPosition implements AsymmetricItem {

  private int columnSpan;
  private int rowSpan;
  private int position;

  public ItemPosition() {
    this(1, 1, 0);
  }

  public ItemPosition(int columnSpan, int rowSpan, int position) {
    this.columnSpan = columnSpan;
    this.rowSpan = rowSpan;
    this.position = position;

  }



  public ItemPosition(Parcel in) {
    readFromParcel(in);
  }

  @Override public int getColumnSpan() {
    return columnSpan;
  }

  @Override public int getRowSpan() {
    return rowSpan;
  }

  public void setColumnSpan(int columnSpan) {
    this.columnSpan = columnSpan;
  }

  public void setPosition(int position) {
    this.position = position;
  }

  public void setRowSpan(int rowSpan) {
    this.rowSpan = rowSpan;
  }

  public int getPosition() {
    return position;
  }

  @Override public String toString() {
    return String.format("%s: %sx%s", position, rowSpan, columnSpan);
  }

  @Override public int describeContents() {
    return 0;
  }

  private void readFromParcel(Parcel in) {
    columnSpan = in.readInt();
    rowSpan = in.readInt();
    position = in.readInt();

  }

  @Override public void writeToParcel(@NonNull Parcel dest, int flags) {
    dest.writeInt(columnSpan);
    dest.writeInt(rowSpan);
    dest.writeInt(position);

  }

  /* Parcelable interface implementation */  public static final Parcelable.Creator<ItemPosition> CREATOR = new Parcelable.Creator<ItemPosition>() {

    @Override public ItemPosition createFromParcel(@NonNull Parcel in) {
      return new ItemPosition(in);
    }

    @Override @NonNull public ItemPosition[] newArray(int size) {
      return new ItemPosition[size];
    }
  };
}


Step - 2 :
Create another POJO(model) class for childView means ImageGrid


package com.at.facebooktypeimagegrid.model;

import android.os.Parcel;

public class ItemImage extends ItemPosition {

   private int ItemImageId;
   private String ImagePath;
   private String Thumb;

   
   public ItemImage(int itemImageId, String imagePath, String thumb) {
      super();
      ItemImageId = itemImageId;
      ImagePath = imagePath;
      Thumb = thumb;

   }

   protected ItemImage(Parcel in) {
      ItemImageId = in.readInt();
      ImagePath = in.readString();
      Thumb = in.readString();

   }

   @Override   public int describeContents() {
      return 0;
   }

   @Override   public void writeToParcel(Parcel dest, int flags) {
      dest.writeInt(ItemImageId);
      dest.writeString(ImagePath);
      dest.writeString(Thumb);

   }

   @Override   public String toString() {
      return "ItemImage{" +
            "ItemImageId=" + ItemImageId +
            ", ImagePath='" + ImagePath + '\'' +
            ", Thumb='" + Thumb + '\'' +
            '}';
   }

   public String getThumb() {
      return Thumb;
   }

   public void setThumb(String thumb) {
      Thumb = thumb;
   }

   public int getItemImageId() {
      return ItemImageId;
   }

   public void setItemImageId(int itemImageId) {
      ItemImageId = itemImageId;
   }

   public String getImagePath() {
      return ImagePath;
   }

   public void setImagePath(String imagePath) {
      ImagePath = imagePath;
   }



   public static final Creator<ItemImage> CREATOR = new Creator<ItemImage>() {
      @Override      public ItemImage createFromParcel(Parcel in) {
         return new ItemImage(in);
      }

      @Override      public ItemImage[] newArray(int size) {
         return new ItemImage[size];
      }
   };

}



Step - 3 :
make childView xml for manage Total Image count and display image



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    android:id="@+id/rlImages"   
    android:layout_width="wrap_content"    
    android:layout_height="wrap_content"    
    android:background="#99000000">

    <ImageView    
        android:id="@+id/mImageView"    
        android:layout_width="match_parent"    
        android:layout_height="match_parent"    
        android:layout_alignParentTop="true"         />

    <TextView    
        android:id="@+id/tvCount"    
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"    
        android:layout_alignBottom="@+id/mImageView"    
        android:layout_alignLeft="@+id/mImageView"    
        android:layout_centerInParent="true"    
        android:gravity="center"    
        android:layout_alignRight="@+id/mImageView"    
        android:layout_alignTop="@+id/mImageView"    
        android:textColor="@android:color/white"    
        android:textSize="20sp"    
       android:text="+6" />
 
   </RelativeLayout>
 
Step - 4 :
Now make childAdapter for making customze grid on every child of ParentView



class ChildAdapter extends AGVRecyclerViewAdapter<ViewHolder> {
    private final List<ItemImage> items;
    private int mDisplay = 0;
    private int mTotal = 0;

    public ChildAdapter(List<ItemImage> items,int mDisplay, int mTotal) {
      this.items = items;
      this.mDisplay = mDisplay;
        this.mTotal = mTotal;

    }




    @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      Log.d("RecyclerViewActivity", "onCreateView");
      return new ViewHolder(parent, viewType,items);
    }

    @Override public void onBindViewHolder(ViewHolder holder, int position) {
      Log.d("RecyclerViewActivity", "onBindView position=" + position);
      holder.bind(items,position,mDisplay,mTotal);
    }

    @Override public int getItemCount() {
      return items.size();
    }

    @Override public AsymmetricItem getItem(int position) {
      return (AsymmetricItem) items.get(position);
    }

    @Override public int getItemViewType(int position) {
      return position % 2 == 0 ? 1 : 0;
    }
  }


  class ViewHolder extends RecyclerView.ViewHolder {
    private final ImageView mImageView;
    private final TextView textView;

    public ViewHolder(ViewGroup parent, int viewType, List<ItemImage> items) {
      super(LayoutInflater.from(parent.getContext()).inflate(
              R.layout.adapter_item, parent, false));

      mImageView = (ImageView) itemView.findViewById(R.id.mImageView);
      textView = (TextView) itemView.findViewById(R.id.tvCount);



    }


    public void bind(List<ItemImage> item, int position, int mDisplay, int mTotal) {
      ImageLoader.getInstance().displayImage(String.valueOf(item.get(position).getImagePath()), mImageView);
      textView.setText("+"+(mTotal-mDisplay));
      if(mTotal > mDisplay)
      {
        if(position  == mDisplay-1) {
          textView.setVisibility(View.VISIBLE);
          mImageView.setAlpha(72);
        }
        else {
          textView.setVisibility(View.INVISIBLE);
          mImageView.setAlpha(255);
        }
      }
      else      {
        mImageView.setAlpha(255);
        textView.setVisibility(View.INVISIBLE);
      }

    }
  }



step - 5 :

make SpaceItemDecoration.java for ItemDecoration for RecyclerView



public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
  private final int padding;

  public SpacesItemDecoration(int padding) {
    this.padding = padding;
  }

  @Override public void getItemOffsets(
      Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    outRect.bottom = padding;
  }
} 
Now Multiple Image grid like facebook is ready
Part - 1
Part - 2
 
for getting full source code you can get from GitHub

Tuesday, 7 June 2016

Best way to display multiple image grid like facebook Part - 1

Here is the example of the step by step integration for displaying multiple image like facebook given as below using AsymmetricGridView Library for support items with colspan and rowspan

AsymmetricGridView is a custom view that implements multiple columns and variable size elements

                                   


Step 1:

 To create a new project in Android Studio

Open Android Studio ---- File ---- New Project --- Set Project Name --- Set API levle etc..---Next,Next,Finish

Step 2:


In your project's gradle file add following dependencies for some librarys

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
    compile 'com.android.support:recyclerview-v7:23.3.0'
    compile 'com.android.support:support-annotations:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'org.jetbrains:annotations-java5:15.0'
    compile 'com.android.support:cardview-v7:23.3.0'
}

Step 3:

Add Asymmetric Library's Source code to your project's package below is the all file listed.



Step 4:
Make MainActivity.java file in your project's package
In AsymmetricGridView colspan and rowspan is a element which use for manag Image for large like merge 2 image view
public class MainActivity extends AppCompatActivity {
    public String Image1 = "https://wellcome.ac.uk/sites/default/files/styles/news_lead/public/G3520217_SPL_LeanGenes_200606_600x600.jpg?itok=3G_cT3lu";
    public String Image2 = "http://rs1054.pbsrc.com/albums/s499/vadimzbanok/1327.jpg~c200";
    public String Image3 = "http://www.pnas.org/site/misc/images/15-02545.500.jpg";
    public String Image4 = "https://s-media-cache-ak0.pinimg.com/736x/7f/47/e4/7f47e4e3f9f3755fcd6012dfe6a7dc12.jpg";

    int currentOffset = 0;
    int mMaxDisplay_Size = 6;
    int mTotal_Size = 0;

    ArrayList<ItemImage> Pathitems = new ArrayList<>();
    private List<ItemList> mItemList = new ArrayList<>();
    private RecyclerView recyclerView;
    private ParentAdapter mAdapter;



    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.parent_view);
       
        for(int k = 0; k < 10;k++) {
            prepareMovieData(k);
        }
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        mTotal_Size = Pathitems.size();
        mAdapter = new ParentAdapter(this,mItemList,mMaxDisplay_Size,mTotal_Size);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);
 

    }
 
    private void prepareMovieData(int k) {


        ArrayList<ItemImage> mPathitems = new ArrayList<>();
        boolean isCol2Avail = false;

        ItemImage i1 = new ItemImage(1,Image1,Image1);
        int colSpan1 = Math.random() < 0.2f ? 2 : 1;
        int rowSpan1 = colSpan1;
        if(colSpan1 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan1 == 2 && isCol2Avail)
            colSpan1 = 1;

        i1.setColumnSpan(colSpan1);
        i1.setRowSpan(rowSpan1);
        i1.setPosition( currentOffset + 0);

        ItemImage i2 = new ItemImage(2,Image2,Image2);
        int colSpan2 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan2 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan2 == 2 && isCol2Avail)
            colSpan2 = 1;

        int rowSpan2 = colSpan2;
        i2.setColumnSpan(colSpan2);
        i2.setRowSpan(rowSpan2);
        i2.setPosition( currentOffset + 1);


        ItemImage i3 = new ItemImage(3,Image3,Image3);
        int colSpan3 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan3 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan3 == 2 && isCol2Avail)
            colSpan3 = 1;

        int rowSpan3 = colSpan3;
        i3.setColumnSpan(colSpan3);
        i3.setRowSpan(rowSpan3);
        i3.setPosition( currentOffset + 2);

        ItemImage i4 = new ItemImage(4,Image4,Image4);
        int colSpan4 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan4 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan4 == 2 && isCol2Avail)
            colSpan4 = 1;

        int rowSpan4 = colSpan4;
        i4.setColumnSpan(colSpan4);
        i4.setRowSpan(rowSpan4);
        i4.setPosition( currentOffset + 3);

        ItemImage i5 = new ItemImage(5,Image1,Image1);
        int colSpan5 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan5 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan5 == 2 && isCol2Avail)
            colSpan5 = 1;

        int rowSpan5 = colSpan5;
        i5.setColumnSpan(colSpan5);
        i5.setRowSpan(rowSpan5);
        i5.setPosition( currentOffset + 4);

        ItemImage i6 = new ItemImage(6,Image2,Image2);
        int colSpan6 = Math.random() < 0.2f ? 2 : 1;

        if(colSpan6 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan6 == 2 && isCol2Avail)
            colSpan6 = 1;

        int rowSpan6 = colSpan6;
        i6.setColumnSpan(colSpan6);
        i6.setRowSpan(rowSpan6);
        i6.setPosition( currentOffset + 5);

        ItemImage i7 = new ItemImage(7,Image3,Image3);
        int colSpan7 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan7 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan7 == 2 && isCol2Avail)
            colSpan7 = 1;

        int rowSpan7 = colSpan7;
        i7.setColumnSpan(colSpan7);
        i7.setRowSpan(rowSpan7);
        i7.setPosition( currentOffset + 6);

        ItemImage i8 = new ItemImage(8,Image4,Image4);
        int colSpan8 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan8 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan8 == 2 && isCol2Avail)
            colSpan8 = 1;

        int rowSpan8 = colSpan8;
        i8.setColumnSpan(colSpan8);
        i8.setRowSpan(rowSpan8);
        i8.setPosition( currentOffset + 7);

        ItemImage i9 = new ItemImage(9,Image2,Image2);
        int colSpan9 = Math.random() < 0.2f ? 2 : 1;
        if(colSpan9 == 2 && !isCol2Avail)
            isCol2Avail = true;
        else if(colSpan9 == 2 && isCol2Avail)
            colSpan9 = 1;

        int rowSpan9 = colSpan9;
        i9.setColumnSpan(colSpan9);
        i9.setRowSpan(rowSpan9);
        i9.setPosition( currentOffset + 8);


        Pathitems.clear();

        Pathitems.add(i1);
        Pathitems.add(i2);
        Pathitems.add(i3);
        Pathitems.add(i4);
        Pathitems.add(i5);
        Pathitems.add(i6);
        Pathitems.add(i7);
        Pathitems.add(i8);
        Pathitems.add(i9);

        for(int i = 0; i < mMaxDisplay_Size;i++)
        {

            mPathitems.add(Pathitems.get(i));
        }



        ItemList itemList = new ItemList(k,"User "+(k+1),mPathitems);
        mItemList.add(itemList);
        currentOffset += mPathitems.size();

    }

    
}


Step 5:
Make parent_view.xml  layout
<?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e5e5e5"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />
</RelativeLayout>





Step 6:
Make ParentAdapter.java  for RecyclerView
public class ParentAdapter extends RecyclerView.Adapter<ParentAdapter.MyViewHolder> {
 
    private List<ItemList> mItemList;
    private Context mCon;
    private int mDisplay= 0;
    private int mTotal= 0;



    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView tvTitle;
        public AsymmetricRecyclerView recyclerView;
 
        public MyViewHolder(View view) {
            super(view);
            tvTitle = (TextView) view.findViewById(R.id.tvTitle);
            recyclerView = (AsymmetricRecyclerView) view.findViewById(R.id.recyclerView);


            recyclerView.setRequestedColumnCount(3);
            recyclerView.setDebugging(true);
            recyclerView.setRequestedHorizontalSpacing(Utils.dpToPx(mCon, 3));
            recyclerView.addItemDecoration(
                    new SpacesItemDecoration(mCon.getResources().getDimensionPixelSize(R.dimen.recycler_padding)));


        }
    }
 
 
    public ParentAdapter(Context con,List<ItemList> moviesList,int max_display, int mTotal_size) {
        mCon = con;
        this.mItemList = moviesList;
        mDisplay = max_display;
        mTotal = mTotal_size;
    }
 
    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.parent_item, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override    public void onBindViewHolder(MyViewHolder holder, int position) {
        ItemList item = mItemList.get(position);
        String title = mCon.getString(R.string.title, item.getItemName(),mTotal+"");
        holder.tvTitle.setText(Html.fromHtml(title));
        ChildAdapter adapter = new ChildAdapter(item.getImages(),mDisplay,mTotal);
        holder.recyclerView.setAdapter(new AsymmetricRecyclerViewAdapter<>(mCon,holder.recyclerView, adapter));
    }
 
    @Override    public int getItemCount() {
        return mItemList.size();
    }
}

Step 7:
Make parent_item.xml  for RecyclerView Adapter Item
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="8dp"
    android:paddingBottom="8dp">
    <android.support.v7.widget.CardView 
        xmlns:card_view="http://schemas.android.com/apk/res-auto"       
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        card_view:cardCornerRadius="1dp">
        <LinearLayout            
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="8dp">
            <RelativeLayout                
                android:id="@+id/rlParent"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
                <ImageView                  
                    android:id="@+id/ivProfile"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_alignParentLeft="true"
                    android:layout_marginBottom="10dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="10dp"
                    android:padding="1dp"
                    android:scaleType="fitXY"
                    android:src="@drawable/ic_launcher" />
                <TextView                   
                    android:id="@+id/tvTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignTop="@+id/ivProfile"
                    android:layout_toRightOf="@+id/ivProfile"
                    android:gravity="left"
                    android:padding="5dp"
                    android:singleLine="false"
                    android:text="Abhi Patel added 7 new photos Abhi Patel added 7 new photos"
                    android:textColor="#000000"
                     />
                <TextView                  
                    android:id="@+id/tvTime"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/tvTitle"
                    android:layout_toRightOf="@+id/ivProfile"
                    android:ellipsize="end"
                    android:gravity="left"
                    android:paddingLeft="5dp"
                    android:singleLine="true"
                    android:text="16 mins ago"
                    android:textColor="#7e7e7e"
                    android:textSize="10sp"
                    android:textStyle="bold" />
            </RelativeLayout>
            <com.at.facebooktypeimagegrid.Assymetric.AsymmetricRecyclerView                
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#ffffff"
                android:divider="@android:color/transparent"
                android:dividerHeight="3dp"
                android:fadingEdge="none"
                android:focusable="false"
                android:gravity="center"
                android:listSelector="#00000000"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>
Step 8:
Make ItemList.java  for RecyclerView Adapter Item POJO class

package com.at.facebooktypeimagegrid.model;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

public class ItemList implements Parcelable {



   private int ItemID;
   private String ItemName;
   private ArrayList<ItemImage> Images;





   public ItemList(int itemID, String itemName,
               ArrayList<ItemImage> itemImages) {
      super();
      ItemID = itemID;
      ItemName = itemName;
      Images = itemImages;


   }


   public int getProductID() {
      return ItemID;
   }

   public void setProductID(int productID) {
      ItemID = productID;
   }


   public String getItemName() {
      return ItemName;
   }

   public void setItemName(String itemName) {
      ItemName = itemName;
   }


   public ArrayList<ItemImage> getImages() {
      return Images;
   }

   public void setImages(ArrayList<ItemImage> images) {
      Images = images;
   }

   @SuppressWarnings({ "rawtypes", "unchecked" })
   protected ItemList(Parcel in) {
      ItemID = in.readInt();
      ItemName = in.readString();
      Images = (ArrayList) in.readValue(ArrayList.class.getClassLoader());

   }

   @Override   public int describeContents() {
      return 0;
   }

   @Override   public void writeToParcel(Parcel dest, int flags) {
      dest.writeInt(ItemID);
      dest.writeString(ItemName);
      dest.writeValue(Images);

   }

   public static final Creator<ItemList> CREATOR = new Creator<ItemList>() {
      @Override      public ItemList createFromParcel(Parcel in) {
         return new ItemList(in);
      }

      @Override      public ItemList[] newArray(int size) {
         return new ItemList[size];
      }
   };

   @Override   public String toString() {
      return "ItemList{" +
            "IID=" + ItemID +
            ", ItemName='" + ItemName + '\'' +
            ", Images=" + Images +
            '}';
   }
}

Here the base structure for facebook grid is ready 
Best way to display multiple image grid like facebook Part - 2 available here.

Thank You
Happy Coding