Friday, July 20, 2012

Implement custom LinearLayout for Gallery-like HorizontalScrollView

Last exercise explain the basic to "implement Gallery-like HorizontalScrollView". In this post, we are going to implement our custom LinearLayout for Gallery-like HorizontalScrollView.

Custom LinearLayout for Gallery-like HorizontalScrollView


MyHorizontalLayout.java, our custom LinearLayout for Gallery-like HorizontalScrollView.
package com.example.androidhorizontalscrollviewgallery;
import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MyHorizontalLayout extends LinearLayout {
 
 Context myContext;
 ArrayList<String> itemList = new ArrayList<String>();

 public MyHorizontalLayout(Context context) {
  super(context);
  myContext = context;
 }

 public MyHorizontalLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
  myContext = context;
 }

 public MyHorizontalLayout(Context context, AttributeSet attrs,
   int defStyle) {
  super(context, attrs, defStyle);
  myContext = context;
 }
 
 void add(String path){
  int newIdx = itemList.size();
  itemList.add(path);
  addView(getImageView(newIdx));
 }
 
 ImageView getImageView(int i){
  Bitmap bm = null;
  if (i < itemList.size()){
   bm = decodeSampledBitmapFromUri(itemList.get(i), 220, 220);
  }
  
  ImageView imageView = new ImageView(myContext);
     imageView.setLayoutParams(new LayoutParams(220, 220));
     imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
     imageView.setImageBitmap(bm);

  return imageView;
 }
 
 public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
     Bitmap bm = null;
     
     // First decode with inJustDecodeBounds=true to check dimensions
     final BitmapFactory.Options options = new BitmapFactory.Options();
     options.inJustDecodeBounds = true;
     BitmapFactory.decodeFile(path, options);
     
     // Calculate inSampleSize
     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
     
     // Decode bitmap with inSampleSize set
     options.inJustDecodeBounds = false;
     bm = BitmapFactory.decodeFile(path, options); 
     
     return bm;  
    }
    
    public int calculateInSampleSize(
      
     BitmapFactory.Options options, int reqWidth, int reqHeight) {
     // Raw height and width of image
     final int height = options.outHeight;
     final int width = options.outWidth;
     int inSampleSize = 1;
        
     if (height > reqHeight || width > reqWidth) {
      if (width > height) {
       inSampleSize = Math.round((float)height / (float)reqHeight);   
      } else {
       inSampleSize = Math.round((float)width / (float)reqWidth);   
      }   
     }
     
     return inSampleSize;   
    }
 
}


Modify layout to include MyHorizontalLayout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:orientation="vertical">

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <com.example.androidhorizontalscrollviewgallery.MyHorizontalLayout
            android:id="@+id/mygallery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            />
    </HorizontalScrollView>

</LinearLayout>


See how simple is the main code:
package com.example.androidhorizontalscrollviewgallery;

import java.io.File;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.widget.Toast;

public class MainActivity extends Activity {

 MyHorizontalLayout myHorizontalLayout;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        myHorizontalLayout = (MyHorizontalLayout)findViewById(R.id.mygallery);
        
        String ExternalStorageDirectoryPath = Environment
          .getExternalStorageDirectory()
          .getAbsolutePath();
        
        String targetPath = ExternalStorageDirectoryPath + "/test/";
        
        Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
        File targetDirector = new File(targetPath);
                 
        File[] files = targetDirector.listFiles();
        for (File file : files){
         myHorizontalLayout.add(file.getAbsolutePath());
        }    
    }
    
}


Download the files.

Next:
- Vertical Gallery-like ScrollView
- Handle onClick for our custom LinearLayout for Gallery-like HorizontalScrollView

Related:
- GridView loading photos from SD Card


6 comments:

Unknown said...

Very useful tutorial
Thanks a lot

Anonymous said...

how to add space between the images in horizontal scrollview?

Erik said...

It can arrange it in getImageView()

Unknown said...

when i execute this code it is showing this error....how to solve this?

Process: com.example.androidhorizontalscrollviewgallery, java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidhorizontalscrollviewgallery/com.example.androidhorizontalscrollviewgallery.MainActivity}: java.lang.NullPointerException


Thank in Advance.

Unknown said...

when i execute this code it is showing this error....how to solve this?

Process: com.example.androidhorizontalscrollviewgallery, java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidhorizontalscrollviewgallery/com.example.androidhorizontalscrollviewgallery.MainActivity}: java.lang.NullPointerException


Thank in Advance.

Rajasekaran said...

I load image from sdcard, it too slow to load image, can u pls explain, how i load fast?