Showing posts with label List View in android.Horizontal listview in android. Show all posts
Showing posts with label List View in android.Horizontal listview in android. Show all posts

Tuesday 13 November 2012

Android horizontal listview | horizontal listview | android listview | android custom horizontal listview

Hello Droid Guys,

In android , there is ListView tag in xml, with the help of this we can show
list view but its apperance is vertically not horizontally and if you want to show
a horizontal listview then you have to make your custom view,


1. Create a new project in Eclipse File New ⇒ Android ⇒ Application Project and fill the required details.
2. Create required files needed to generate a list view. I am using  activity_horizontal_list_view.xml as list view and created a new xml file for single list item named  listview_item.xml

horizontal list view example
Horizontal listView

activity_horizontal_list_view.xml 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/selected_imageview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@+id/gallery_relative_layout"
        android:layout_marginLeft="30dip"
        android:layout_marginRight="30dip"
        android:layout_marginTop="30dip"
        android:background="@drawable/natureimage1" />
    <RelativeLayout
        android:id="@+id/gallery_relative_layout"
        android:layout_width="wrap_content"
        android:layout_height="150dip"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >
        <com.mukesh.ui.HorizontalView
            android:id="@+id/gallery"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:layout_marginLeft="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginTop="15dp"
            android:smoothScrollbar="true"
            android:spacing="20dip" >
        </com.mukesh.ui.HorizontalView>
    </RelativeLayout>
</RelativeLayout>
listview_item.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="72dp"
        android:layout_height="75dp" />

</RelativeLayout>





3. HorizontalView.Java : These class help us to create view. This is my custom 
               view class which help us in showing listview Horizontally.
     

package com.mukesh.ui;

import java.util.LinkedList;
import java.util.Queue;

import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;

public class HorizontalView extends AdapterView {

 public boolean mAlwaysOverrideTouch = true;
 protected ListAdapter mAdapter;
 private int mLeftViewIndex = -1;
 private int mRightViewIndex = 0;
 protected int mCurrentX;
 protected int mNextX;
 private int mMaxX = Integer.MAX_VALUE;
 private int mDisplayOffset = 0;
 protected Scroller mScroller;
 private GestureDetector mGesture;
 private Queue mRemovedViewQueue = new LinkedList();
 private OnItemSelectedListener mOnItemSelected;
 private OnItemClickListener mOnItemClicked;
 private OnItemLongClickListener mOnItemLongClicked;
 private boolean mDataChanged = false;

 public HorizontalView(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView();
 }

 private synchronized void initView() {
  mLeftViewIndex = -1;
  mRightViewIndex = 0;
  mDisplayOffset = 0;
  mCurrentX = 0;
  mNextX = 0;
  mMaxX = Integer.MAX_VALUE;
  mScroller = new Scroller(getContext());
  mGesture = new GestureDetector(getContext(), mOnGesture);
 }

 @Override
 public void setOnItemSelectedListener(
   AdapterView.OnItemSelectedListener listener) {
  mOnItemSelected = listener;
 }

 @Override
 public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
  mOnItemClicked = listener;
 }

 @Override
 public void setOnItemLongClickListener(
   AdapterView.OnItemLongClickListener listener) {
  mOnItemLongClicked = listener;
 }

 private DataSetObserver mDataObserver = new DataSetObserver() {

  @Override
  public void onChanged() {
   synchronized (HorizontalView.this) {
    mDataChanged = true;
   }
   invalidate();
   requestLayout();
  }

  @Override
  public void onInvalidated() {
   reset();
   invalidate();
   requestLayout();
  }

 };

 @Override
 public ListAdapter getAdapter() {
  return mAdapter;
 }

 @Override
 public View getSelectedView() {
  // TODO: implement
  return null;
 }

 @Override
 public void setAdapter(ListAdapter adapter) {
  if (mAdapter != null) {
   mAdapter.unregisterDataSetObserver(mDataObserver);
  }
  mAdapter = adapter;
  mAdapter.registerDataSetObserver(mDataObserver);
  reset();
 }

 private synchronized void reset() {
  initView();
  removeAllViewsInLayout();
  requestLayout();
 }

 @Override
 public void setSelection(int position) {
  // TODO: implement
 }

 private void addAndMeasureChild(final View child, int viewPos) {
  LayoutParams params = child.getLayoutParams();
  if (params == null) {
   params = new LayoutParams(LayoutParams.FILL_PARENT,
     LayoutParams.FILL_PARENT);
  }

  addViewInLayout(child, viewPos, params, true);
  child.measure(
    MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
    MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
 }

 @Override
 protected synchronized void onLayout(boolean changed, int left, int top,
   int right, int bottom) {
  super.onLayout(changed, left, top, right, bottom);

  if (mAdapter == null) {
   return;
  }

  if (mDataChanged) {
   int oldCurrentX = mCurrentX;
   initView();
   removeAllViewsInLayout();
   mNextX = oldCurrentX;
   mDataChanged = false;
  }

  if (mScroller.computeScrollOffset()) {
   int scrollx = mScroller.getCurrX();
   mNextX = scrollx;
  }

  if (mNextX <= 0) {
   mNextX = 0;
   mScroller.forceFinished(true);
  }
  if (mNextX >= mMaxX) {
   mNextX = mMaxX;
   mScroller.forceFinished(true);
  }

  int dx = mCurrentX - mNextX;

  // removeNonVisibleItems(dx);
  fillList(dx);
  positionItems(dx);

  mCurrentX = mNextX;

  if (!mScroller.isFinished()) {
   post(new Runnable() {
    @Override
    public void run() {
     requestLayout();
    }
   });

  }
 }

 private void fillList(final int dx) {
  int edge = 0;
  View child = getChildAt(getChildCount() - 1);
  if (child != null) {
   edge = child.getRight();
  }
  fillListRight(edge, dx);

  edge = 0;
  child = getChildAt(0);
  if (child != null) {
   edge = child.getLeft();
  }
  fillListLeft(edge, dx);

 }

 private void fillListRight(int rightEdge, final int dx) {
  while (rightEdge + dx < getWidth()
    && mRightViewIndex < mAdapter.getCount()) {

   View child = mAdapter.getView(mRightViewIndex,
     mRemovedViewQueue.poll(), this);
   addAndMeasureChild(child, -1);
   rightEdge += child.getMeasuredWidth();

   if (mRightViewIndex == mAdapter.getCount() - 1) {
    mMaxX = mCurrentX + rightEdge - getWidth();
   }

   if (mMaxX < 0) {
    mMaxX = 0;
   }
   mRightViewIndex++;
  }

 }

 private void fillListLeft(int leftEdge, final int dx) {
  while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
   View child = mAdapter.getView(mLeftViewIndex,
     mRemovedViewQueue.poll(), this);
   addAndMeasureChild(child, 0);
   leftEdge -= child.getMeasuredWidth();
   mLeftViewIndex--;
   mDisplayOffset -= child.getMeasuredWidth();
  }
 }

 /*
  * private void removeNonVisibleItems(final int dx) { View child =
  * getChildAt(0); while(child != null && child.getRight() + dx <= 0) {
  * mDisplayOffset += child.getMeasuredWidth();
  * mRemovedViewQueue.offer(child); removeViewInLayout(child);
  * mLeftViewIndex++; child = getChildAt(0);
  * 
  * }
  * 
  * child = getChildAt(getChildCount()-1); while(child != null &&
  * child.getLeft() + dx >= getWidth()) { mRemovedViewQueue.offer(child);
  * removeViewInLayout(child); mRightViewIndex--; child =
  * getChildAt(getChildCount()-1); } }
  */

 private void positionItems(final int dx) {
  if (getChildCount() > 0) {
   mDisplayOffset += dx;
   int left = mDisplayOffset;
   for (int i = 0; i < getChildCount(); i++) {
    View child = getChildAt(i);
    int childWidth = child.getMeasuredWidth();
    child.layout(left, 0, left + childWidth,
      child.getMeasuredHeight());
    left += childWidth;
   }
  }
 }

 public synchronized void scrollTo(int x) {
  mScroller.startScroll(mNextX, 0, x - mNextX, 0);
  requestLayout();
 }

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  boolean handled = super.dispatchTouchEvent(ev);
  handled |= mGesture.onTouchEvent(ev);
  return handled;
 }

 protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
   float velocityY) {
  synchronized (HorizontalView.this) {
   mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);
  }
  requestLayout();

  return true;
 }

 protected boolean onDown(MotionEvent e) {
  mScroller.forceFinished(true);
  return true;
 }

 private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {

  @Override
  public boolean onDown(MotionEvent e) {
   return HorizontalView.this.onDown(e);
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    float velocityY) {
   return HorizontalView.this.onFling(e1, e2, velocityX, velocityY);
  }

  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2,
    float distanceX, float distanceY) {

   synchronized (HorizontalView.this) {
    mNextX += (int) distanceX;
   }
   requestLayout();

   return true;
  }

  @Override
  public boolean onSingleTapConfirmed(MotionEvent e) {
   for (int i = 0; i < getChildCount(); i++) {
    View child = getChildAt(i);
    if (isEventWithinView(e, child)) {
     if (mOnItemClicked != null) {
      mOnItemClicked.onItemClick(HorizontalView.this, child,
        mLeftViewIndex + 1 + i,
        mAdapter.getItemId(mLeftViewIndex + 1 + i));
     }
     if (mOnItemSelected != null) {
      mOnItemSelected.onItemSelected(HorizontalView.this,
        child, mLeftViewIndex + 1 + i,
        mAdapter.getItemId(mLeftViewIndex + 1 + i));
     }
     break;
    }

   }
   return true;
  }

  @Override
  public void onLongPress(MotionEvent e) {
   int childCount = getChildCount();
   for (int i = 0; i < childCount; i++) {
    View child = getChildAt(i);
    if (isEventWithinView(e, child)) {
     if (mOnItemLongClicked != null) {
      mOnItemLongClicked.onItemLongClick(HorizontalView.this,
        child, mLeftViewIndex + 1 + i,
        mAdapter.getItemId(mLeftViewIndex + 1 + i));
     }
     break;
    }

   }
  }

  private boolean isEventWithinView(MotionEvent e, View child) {
   Rect viewRect = new Rect();
   int[] childPosition = new int[2];
   child.getLocationOnScreen(childPosition);
   int left = childPosition[0];
   int right = left + child.getWidth();
   int top = childPosition[1];
   int bottom = top + child.getHeight();
   viewRect.set(left, top, right, bottom);
   return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
  }
 };

}




4. Now my Activity class(HorizontalListView.java ) and adapter class
   (HorizontalImageAdapter.java )




A.HorizontalListView.java


package com.mukesh.horizontallistview;

import java.util.ArrayList;
import java.util.List;

import com.mukesh.ui.HorizontalView;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.Drawable;

public class HorizontalListView extends Activity {

 private List drawables;
 private HorizontalImageAdapter imageAdapter;
 private HorizontalView listView;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_horizontal_list_view);

  listView = (HorizontalView) findViewById(R.id.gallery);
  getDrawablesList();
  setupUI();
 }

 private void setupUI() {
  imageAdapter = new HorizontalImageAdapter(this, drawables);

  listView.setAdapter(imageAdapter);

 }

 private void getDrawablesList() {

      drawables = new ArrayList();
      drawables.add(getResources().getDrawable(R.drawable.natureimage1));
      drawables.add(getResources().getDrawable(R.drawable.natureimage2));
      drawables.add(getResources().getDrawable(R.drawable.natureimage3));
      drawables.add(getResources().getDrawable(R.drawable.natureimage4));
      drawables.add(getResources().getDrawable(R.drawable.natureimage5));
      drawables.add(getResources().getDrawable(R.drawable.natureimage6));
      drawables.add(getResources().getDrawable(R.drawable.natureimage7));
      drawables.add(getResources().getDrawable(R.drawable.natureimage8));
      drawables.add(getResources().getDrawable(R.drawable.natureimage9));
      drawables.add(getResources().getDrawable(R.drawable.natureimage10));
      drawables.add(getResources().getDrawable(R.drawable.natureimage12));
      drawables.add(getResources().getDrawable(R.drawable.natureimage13));
      drawables.add(getResources().getDrawable(R.drawable.natureimage15));

 }

}




B. HorizontalImageAdapter.java 
package com.mukesh.horizontallistview; import java.util.List; import android.app.Activity; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; public class HorizontalImageAdapter extends BaseAdapter { private Activity context; private static ImageView imageView; private List plotsImages; private static ViewHolder holder; private LayoutInflater l_Inflater; public HorizontalImageAdapter(Activity context, List plotsImages) { this.context = context; this.plotsImages = plotsImages; l_Inflater = LayoutInflater.from(context); } @Override public int getCount() { return plotsImages.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { holder = new ViewHolder(); convertView = l_Inflater.inflate(R.layout.listview_item, null); holder = new ViewHolder(); holder.imageView = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.imageView.setImageDrawable(plotsImages.get(position)); return convertView; } private static class ViewHolder { ImageView imageView; } }


This is what I am doing to show Horizontal listviw in android.


Cheers :)
Enjoy Coding....

 

Copyright @ 2013 Android Developers Blog.