Created
May 9, 2014 20:42
-
-
Save libinbensin/9fff896d5d234e8209c4 to your computer and use it in GitHub Desktop.
HorizontalListView to add items horizontally
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.database.DataSetObserver; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.widget.Adapter; | |
import android.widget.BaseAdapter; | |
import android.widget.HorizontalScrollView; | |
import android.widget.LinearLayout; | |
/** | |
* A custom widget to display the list items in horizontal direction | |
* <p/> | |
* Do not try to add view directly to this HorizontalListView, | |
* as HorizontalScrollView supports only one child Layout. | |
* <p/> | |
* Created by libin on 5/8/14. | |
*/ | |
public class HorizontalListView extends HorizontalScrollView implements View.OnClickListener { | |
private final Context mContext; | |
/** | |
* layout to hold list items | |
*/ | |
private LinearLayout mParent; | |
/** | |
* listener for list item click | |
*/ | |
private OnItemClickListener mOnItemClickListener; | |
/** | |
* adapter to fill data to list items | |
*/ | |
private BaseAdapter mAdapter; | |
/** | |
* Data observer to listener for change in the adapter data | |
*/ | |
AbstractDataSetObserver mDataSetObserver; | |
/** | |
* Simple constructor to use when creating a view from code. | |
* | |
* @param context The content which the view is running in , | |
* through which can access the themes , resources , etc. | |
*/ | |
public HorizontalListView(Context context) { | |
super(context); | |
this.mContext = context; | |
} | |
/** | |
* Constructor that is called when inflating a view from XML. | |
* A Child layout is added to the parent View, to hold the list items. | |
* | |
* @param context The content which the view is running in , | |
* through which can access the themes , resources , etc. | |
* @param attrs The attributes of the XML tag that is inflating the view. | |
*/ | |
public HorizontalListView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
this.mContext = context; | |
} | |
/** | |
* Sets the adapter to this HorizontalListView | |
* | |
* @param adapter an adapter which provides item data | |
*/ | |
public void setAdapter(BaseAdapter adapter) { | |
// unregister the old data observer | |
if (mAdapter != null && mDataSetObserver != null) { | |
mAdapter.unregisterDataSetObserver(mDataSetObserver); | |
mDataSetObserver = null; | |
} | |
// set the adapter | |
mAdapter = adapter; | |
// register the new data observer | |
if (mAdapter != null) { | |
mDataSetObserver = new AbstractDataSetObserver(); | |
mAdapter.registerDataSetObserver(mDataSetObserver); | |
} | |
// refresh the layout | |
refreshLayout(); | |
} | |
/** | |
* Get the adapter set to this HorizontalListView | |
* | |
* @return the adapter | |
*/ | |
public Adapter getAdapter() { | |
return mAdapter; | |
} | |
/** | |
* Clear the list items | |
*/ | |
public void clear() { | |
if(this.mParent != null) { | |
mParent.removeAllViewsInLayout(); | |
} | |
} | |
/** | |
* refresh the list with new items from adapter | |
*/ | |
void refreshLayout() { | |
// remove all the existing items | |
if(this.mParent != null) { | |
this.removeAllViewsInLayout(); | |
} | |
// re initialize the parent view | |
this.mParent = new LinearLayout(mContext); | |
int itemCount = mAdapter.getCount(); | |
int index = 0; | |
while (index < itemCount) { | |
View child = obtainView(index); | |
if (child != null) { | |
// add the child to parent | |
addItemView(child, index); | |
index++; | |
} | |
} | |
// add the parent view | |
this.addView(mParent); | |
} | |
/** | |
* add view items to HorizontalListView | |
* | |
* @param child the child view | |
* @param index index of the child view | |
*/ | |
private void addItemView(View child, int index) { | |
setupItemView(child, index); | |
this.mParent.addView(child, index); | |
} | |
private void setupItemView(View view, int index) { | |
// set some default padding | |
view.requestFocusFromTouch(); | |
view.setPadding(2, 0, 2, 0); | |
view.setOnClickListener(this); | |
view.setTag(index); | |
} | |
private View obtainView(int position) { | |
View child = mAdapter.getView(position, null, this); | |
return child; | |
} | |
@Override | |
protected void onAttachedToWindow() { | |
super.onAttachedToWindow(); | |
if (mAdapter != null && mDataSetObserver == null) { | |
mDataSetObserver = new AbstractDataSetObserver(); | |
mAdapter.registerDataSetObserver(mDataSetObserver); | |
} | |
} | |
@Override | |
protected void onDetachedFromWindow() { | |
super.onDetachedFromWindow(); | |
if (mAdapter != null && mDataSetObserver != null) { | |
mAdapter.unregisterDataSetObserver(mDataSetObserver); | |
mDataSetObserver = null; | |
} | |
this.mOnItemClickListener = null; | |
} | |
/** | |
* Sets an listener for HorizontalListView items clicks | |
* | |
* @param listener an OnItemClickListener | |
*/ | |
public void setOnItemClickListener(OnItemClickListener listener) { | |
this.mOnItemClickListener = listener; | |
} | |
/** | |
* An method invoked when an item in HorizontalListView is clicked | |
* | |
* @param view | |
*/ | |
@Override | |
public void onClick(View view) { | |
if (this.mOnItemClickListener != null) { | |
this.mOnItemClickListener.onItemClick(view, (Integer) view.getTag()); | |
} | |
} | |
/** | |
* An interface to handle the HorizontalListView item ClickListener | |
*/ | |
public static interface OnItemClickListener { | |
public void onItemClick(View view, int position); | |
} | |
/** | |
* An data observer to listener for the change in the adapter data | |
*/ | |
private class AbstractDataSetObserver extends DataSetObserver { | |
@Override | |
public void onChanged() { | |
super.onChanged(); | |
// refresh the view | |
refreshLayout(); | |
} | |
@Override | |
public void onInvalidated() { | |
super.onInvalidated(); | |
// refresh the view | |
refreshLayout(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment