I have been using mergeAdapter to merge together multiple list view without any problem. And right now, i'd like to use it to merge together a list view at the top, a horizontalscrollview in the middle and another list view at the bottom, but so far... i couldn't figure out how to do it. It would be great if someone could give me a hand...
Below is my existing code.
MyActivity
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_a);
lv = (ListView) findViewById(R.id.list_all);
adapter=new MergeAdapter();
infoArray = new ArrayList<Infos>();
photoArray = new ArrayList<Photos>();
commentArray = new ArrayList<Comments>();
infoAdapter = new InfoAdapter(MyActivity.this, R.layout.info_list_layout, infoArray);
/// photoAdapter = new PhotoAdapter(MyActivity.this, R.layout.photo_hscroll_layout, photoArray); /// STUCK
commentAdapter = new CommentAdapter(MyActivity.this, R.layout.comment_list_layout, commentArray);
lv.setTextFilterEnabled(true);
adapter.addAdapter(infoAdapter);
/// adapter.addAdapter(photoAdapter); //// STUCK
adapter.addAdapter(commentAdapter);
lv.setAdapter(adapter);
try {
new stuffSync().execute("http://www.StuckForDays.com/json");
} catch(Exception e) {}
}
private class stuffSync extends AsyncTask<String, Integer, stuffDetail> {
protected stuffDetail doInBackground(String... urls) {
stuffDetail list = null;
int count = urls.length;
for (int i = 0; i < count; i++) {
try {
//rest client
RestClient client = new RestClient(urls[i]);
try {
client.Execute(RequestMethod.GET);
} catch (Exception e) {
e.printStackTrace();
}
String json = client.getResponse();
list = new Gson().fromJson(json, stuffDetail.class);
//
} catch(Exception e) {}
}
return list;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(stuffDetail list) {
List<Infos> info = list.getInfo();
for (Infos info2 : info) {
infoArray.add(info2);
}
List<Photos> photos = list.getPhotos();
for (Photos photo : photos) {
photoArray.add(photo);
System.out.println(photo);
}
List<Comments> comments = list.getComments();
for (Comments comment : comments) {
commentArray.add(comment);
}
infoAdapter.notifyDataSetChanged();
// photoAdapter.notifyDataSetChanged(); //// STUCK
commentAdapter.notifyDataSetChanged();
}
}
infoAdapter and commentAdapter (pretty much the same)
public class InfoAdapter extends ArrayAdapter<Infos> {
int resource;
String response;
Context context;
private LayoutInflater dInflater;
public InfoAdapter(Context context, int resource, List<Infos> objects) {
super(context, resource, objects);
this.resource = resource;
dInflater = LayoutInflater.from(context);
}
static class ViewHolder {
TextView realname;
TextView nickname;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
Infos lm = (Infos) getItem(position);
//Inflate the view
if(convertView==null)
{
convertView = dInflater.inflate(R.layout.info_list_layout, null);
holder = new ViewHolder();
holder.realname = (TextView) convertView.findViewById(R.id.realname);
holder.nickname = (TextView) convertView.findViewById(R.id.nickname);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.realname.setText(lm.getRealName());
holder.nickname.setText(lm.getNickname());
return convertView;
}
}
my photo json
{
"photos" : [
{
"thumbnail" : "http://www.myserver.com/01.jpg"
},
{
"thumbnail" : "http://www.myserver.com/02.jpg"
},
{
"thumbnail" : "http://www.myserver.com/03.jpg"
}
]}
And now i am stuck on how to get the photoArray to create the middle section horizontal scroll view... i could get the json and add them to the photoArray, just don't know how to extract, create the view and show it.
thanks all in advance
i think problem solve with horizontal scroll view.. this is a custom control..
import java.util.HashMap;
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 HorizontalListView extends AdapterView<ListAdapter> {
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<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;
private boolean mMeasureHeightForVisibleOnly = true;
public HorizontalListView(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(HorizontalListView.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();
}
/**
* #param visibleOnly - If set to true, then height is calculated
* only using visible views. If set to false then height is
* calculated using _all_ views in adapter. Default is true.
* Be very careful when passing false, as this may result in
* significant performance hit for larger number of views.
*/
public void setHeightMeasureMode(boolean visibleOnly) {
if(mMeasureHeightForVisibleOnly != visibleOnly) {
mMeasureHeightForVisibleOnly = visibleOnly;
requestLayout();
}
}
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 void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
int height = 0;
if(mMeasureHeightForVisibleOnly) {
int childCount = getChildCount();
for(int i = 0; i < childCount; i++) {
View v = getChildAt(i);
v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if(v.getMeasuredHeight() > height) {
height = v.getMeasuredHeight();
}
}
} else {
/* Traverses _all_ views! Bypasses view recycler! */
HashMap<Integer, View> mRecycler = new HashMap<Integer, View>();
int childCount = getAdapter().getCount();
for(int i = 0; i < childCount; i++) {
int type = getAdapter().getItemViewType(i);
View convertView = mRecycler.get(type);
View v = getAdapter().getView(i, convertView, this);
mRecycler.put(type, v);
v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if(v.getMeasuredHeight() > height) {
height = v.getMeasuredHeight();
}
}
}
if(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
if(maxHeight < height) {
height = maxHeight;
}
}
setMeasuredDimension(getMeasuredWidth(), height);
}
}
#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(){
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(HorizontalListView.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 HorizontalListView.this.onDown(e);
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
synchronized(HorizontalListView.this){
mNextX += (int)distanceX;
}
requestLayout();
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Rect viewRect = new Rect();
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if(viewRect.contains((int)e.getX(), (int)e.getY())){
if(mOnItemClicked != null){
mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
break;
}
}
return true;
}
#Override
public void onLongPress(MotionEvent e) {
Rect viewRect = new Rect();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if (viewRect.contains((int) e.getX(), (int) e.getY())) {
if (mOnItemLongClicked != null) {
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
}
};
}
and you can set data in this same as a custom listadapter in listview.
here is the custom adapter
private class ListAdapter extends ArrayAdapter<bin> { // --CloneChangeRequired
private ArrayList<bin> mList; // --CloneChangeRequired
ImageView img;
TextView title;
String id;
public ListAdapter(Context context, int textViewResourceId,
ArrayList<bin> list) { // --CloneChangeRequired
super(context, textViewResourceId, list);
this.mList = list;
imageLoader = new ImageLoader(YoutubeplayerActivity.this
.getApplicationContext());
}
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
try {
if (view == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.cuslistview, null); // --CloneChangeRequired(list_item)
}
img = (ImageView) view.findViewById(R.id.imageView1);
title = (TextView) view.findViewById(R.id.textView1);
final bin listItem = mList.get(position);
// --CloneChangeRequired
if (listItem != null) {
id = listItem.getId();
imageLoader.DisplayImage(listItem.getThumbnail(), img);
title.setText(listItem.getTitle());
rlv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
}
} catch (Exception e) {
Log.v("log", "" + e.toString());
}
return view;
}
}
you can bind data in horizontal listview
HorizonatlListView hv = (HorizontalListView) findviewbyId(R.id.hv1);
hv.setadater(new ListAdapter(getApplicationContext,R.id.hv1,ArrayList<bin>));
Related
I want to make a Horizontal listview, but i don't want to use the library of third-party. So, i try to use PagerAdapter but i can do it.
I don't know how to fix it.
This is my code i use to load photo:
public class GalleryActivity extends AppCompatActivity {
public static final String TAG = "GalleryActivity";
public static final String EXTRA_NAME = "images";
ArrayList<Actor> actors = new ArrayList<>();
private GalleryPagerAdapter _adapter;
#InjectView(R.id.pager) ViewPager _pager;
#InjectView(R.id.thumbnails) LinearLayout _thumbnails;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
ButterKnife.inject(this);
importActor();
_adapter = new GalleryPagerAdapter(this);
_pager.setAdapter(_adapter);
_pager.setOffscreenPageLimit(6);
}
public void importActor(){
Bitmap bitmap = BitmapFactory.decodeResource(GalleryActivity.this.getResources(), R.drawable.nhaphuong);
Bitmap bitmap1 = BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.subo);
Bitmap bitmap2 = BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.truonggiang);
Actor actor = new Actor(5,"Nhã Phương",bitmap);
Actor actor1 = new Actor(15,"Trường Giang",bitmap2);
Actor actor2 = new Actor(999,"Subo",bitmap1);
actors.add(actor);
actors.add(actor1);
actors.add(actor2);
}
class GalleryPagerAdapter extends PagerAdapter {
Context _context;
LayoutInflater _inflater;
public GalleryPagerAdapter(Context context) {
_context = context;
_inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return actors.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = _inflater.inflate(R.layout.one_actor, container, false);
container.addView(view);
// Get the border size to show around each image
int borderSize = _thumbnails.getPaddingTop();
// Get the size of the actual thumbnail image
int thumbnailSize = ((FrameLayout.LayoutParams)
_pager.getLayoutParams()).bottomMargin - (borderSize*2);
// Set the thumbnail layout parameters. Adjust as required
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(thumbnailSize, thumbnailSize);
params.setMargins(0, 0, borderSize, 0);
OneActor oneActor = new OneActor();
oneActor.avatar = (ImageView) view.findViewById(R.id.imgActor);
oneActor.name = (TextView) view.findViewById(R.id.tvActorName);
oneActor.cmtCount = (TextView) view.findViewById(R.id.tvCmtCount);
view.setTag(oneActor);
oneActor.avatar.setImageBitmap(actors.get(position).getAvatar());
oneActor.cmtCount.setText(actors.get(position).getCmtcout() + "");
oneActor.name.setText(actors.get(position).getName());
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
class OneActor{
ImageView avatar;
TextView name, cmtCount;
}
}
This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_gravity="center">
<LinearLayout
android:id="#+id/thumbnails"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingTop="2dp"/>
</HorizontalScrollView>
Tell my how to fix it or give me a tutoral please!
You have to use RecyclerView if you dont have to use it then use HorizontalListView. see below code for HorizontalListView
HorizontalListView.java
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.util.Log;
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 HorizontalListView extends AdapterView<ListAdapter> {
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<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
public HorizontalListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private 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;
Log.v("log_tag", "Message is set On Clicked");
}
#Override
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
mOnItemClicked = listener;
Log.v("log_tag", "Set on Item Clicked");
}
private DataSetObserver mDataObserver=new DataSetObserver(){
#Override public void onChanged(){
// TODO Auto-generated method stub
super.onChanged();}
#Override public void onInvalidated(){
// TODO Auto-generated method stub
super.onInvalidated();}
};
#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);
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 (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();
}
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 = mGesture.onTouchEvent(ev);
return super.dispatchTouchEvent(ev);
}
protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
synchronized (HorizontalListView.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 HorizontalListView.this.onDown(e);}
#Override public boolean onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY){return HorizontalListView.this.onFling(e1,e2,velocityX,velocityY);}
#Override public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY){
synchronized(HorizontalListView.this){mNextX+=(int)distanceX;}requestLayout();
return true;}
#Override public boolean onSingleTapConfirmed(MotionEvent e){Rect viewRect=new Rect();for(int i=0;i<getChildCount();i++){View child=getChildAt(i);int left=child.getLeft();int right=child.getRight();int top=child.getTop();int bottom=child.getBottom();viewRect.set(left,top,right,bottom);if(viewRect.contains((int)e.getX(),(int)e.getY())){if(mOnItemClicked!=null){mOnItemClicked.onItemClick(HorizontalListView.this,child,mLeftViewIndex+1+i,0);}if(mOnItemSelected!=null){mOnItemSelected.onItemSelected(HorizontalListView.this,child,mLeftViewIndex+1+i,0);}break;}
}return true;}
};
}
Use in xml as listview as like
<youpackage.HorizantalListView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Better to use RecyclerView. it worked as HorizontalListView also and it does not require any third party library.
for this you need to do something like this
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
I have made a custom Horizontal List View,Which is working very fine,But i want to do one thing,that when any list item is selected,It should be stayed highlighted till another item is selected,I have tried as below,but its not working.Please help me what changes should i make to make it happen.Thank you.My code is as below:
adapter
public class myhorizontalAdapter extends BaseAdapter {
public ArrayList<HashMap<String, String>> photoArray;
private Context mContext;
private DisplayImageOptions options;
public static ImageLoader imageLoader;
String photoImg;
String query = "http://test.fortalented.com/manage/";
Intent i;
String camera, description, captured_date, date_modified, category,
date_added, candidate_name, big_img;
GifWebView view;
#SuppressWarnings({ "deprecation" })
public myhorizontalAdapter(Context paramContext,
ArrayList<HashMap<String, String>> photoList) {
this.mContext = paramContext;
this.photoArray = photoList;
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(paramContext));
options = new DisplayImageOptions.Builder().cacheOnDisc(true)
.displayer(new RoundedBitmapDisplayer(10))
.showStubImage(R.drawable.wait)
.showImageOnFail(R.drawable.wait).build();
}
public int getCount() {
return this.photoArray.size();
}
public Object getItem(int paramInt) {
return Integer.valueOf(paramInt);
}
public long getItemId(int paramInt) {
return paramInt;
}
public View getView(final int paramInt, View paramView,
ViewGroup paramViewGroup) {
LayoutInflater localLayoutInflater = (LayoutInflater) this.mContext
.getSystemService("layout_inflater");
Viewholder localViewholder = null;
if (paramView == null) {
paramView = localLayoutInflater.inflate(R.layout.viewitem,
paramViewGroup, false);
localViewholder = new Viewholder();
localViewholder.iv_photo = ((ImageView) paramView
.findViewById(R.id.image));
paramView.setBackgroundResource(R.drawable.bg_edittext_selctor);
// New
paramView.setTag(localViewholder);
} else {
localViewholder = (Viewholder) paramView.getTag();
}
ImageLoader.getInstance().displayImage(
query + photoArray.get(paramInt).get("thumbnail"),
localViewholder.iv_photo, options);
return paramView;
}
static class Viewholder {
ImageView iv_photo;
}
}
HorizontalListView
package com.eps.fortalented.uc;
public class HorizontalListView extends AdapterView<ListAdapter> {
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<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;
public HorizontalListView(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(HorizontalListView.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(){
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(HorizontalListView.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 HorizontalListView.this.onDown(e);
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
synchronized(HorizontalListView.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(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.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(HorizontalListView.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());
}
};
}
Activity.java
HorizontalListView smallSlideList;
smallSlideList = (HorizontalListView) findViewById(R.id.listview);
smallSlideList.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
System.out.println(":::::::::::::::::ID::::::::::::::::::::::"
+ arg2);
pos = arg2;
smallSlideList.setSelection(pos);
myPager.setCurrentItem(pos);
picadapter.notifyDataSetChanged();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#aabbcc"/>
<!-- pressed -->
<item android:state_activated="true" android:color="#fedcba"/>
<!-- selected -->
<item android:color="#abcdef"/>
<!-- default -->
</selector>
ViewItem
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/image"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="1dp"
android:scaleType="fitXY" />
</RelativeLayout>
main.xml
<com.eps.fortalented.uc.HorizontalListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_below="#+id/tv_candi"
android:cacheColorHint="#fff"
android:choiceMode="singleChoice"
android:divider="#cdc9c9"
android:dividerHeight="2sp" />
I have a sample project which shows how to set item as selected in custom list: https://github.com/how954/custom-list-item-selection Maybe this helps you.
How to change background color when clicking on Horizontal Listview items in Android
So that users will know where they clicked.
Below is the code which I got from some internet site.
HorizontalListViewActivity.java
public class HorizontalListViewActivity extends Activity {
static BitmapFactory bf;
ArrayList<String> dataObjectsList = new ArrayList<String>();
ArrayList<Bitmap> myImageList = new ArrayList<Bitmap>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
HorizontalListView listview = (HorizontalListView) findViewById(R.id.listview);
listview.setAdapter(mAdapter);
dataObjectsList.add("Text #1");
dataObjectsList.add("Text #2");
dataObjectsList.add("Text #3");
dataObjectsList.add("Text #4");
myImageList.add(BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/Restaurent/app1.jpg"));
myImageList.add(BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/Restaurent/app2.jpg"));
myImageList.add(BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/Restaurent/app3.jpg"));
myImageList.add(BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/Restaurent/app4.jpg"));
listview.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
/*Toast.makeText(getApplicationContext(), "dataObjects[position]=="+dataObjectsList.get(arg2).toString(), 100).show();
Intent intent2 = new Intent(getApplicationContext(),Test.class);
intent2.putExtra("category", dataObjectsList.get(arg2).toString());
startActivity(intent2);*/
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
private static String[] dataObjects = new String[]{ "Delhi",
"Bangalore",
"Chennai",
"Pune" };
private static Bitmap[] myImage = new Bitmap[]{ BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/Restaurent/app1.jpg"),
BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/City/app2.jpg"),
BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/City/app3.jpg"),
BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/City/app4.jpg") };
private BaseAdapter mAdapter = new BaseAdapter() {
#Override
public int getCount() {
return dataObjects.length;
}
#Override
public Object getItem(int position) {
Toast.makeText(getApplicationContext(), "getItem 111111 position=="+position, 100).show();
return null;
}
#Override
public long getItemId(int position) {
Toast.makeText(getApplicationContext(), "getItemId position=="+position, 100).show();
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);
TextView title = (TextView) retval.findViewById(R.id.title);
ImageView img=(ImageView) retval.findViewById(R.id.image);
img.setImageBitmap(myImageList.get(position));
title.setText(dataObjectsList.get(position).toString());
return retval;
}
};
}
HorizontalListView.java
public class HorizontalListView extends AdapterView<ListAdapter> {
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<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;
public HorizontalListView(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(HorizontalListView.this){
mDataChanged = true;
}
setEmptyView(getEmptyView());
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 = mGesture.onTouchEvent(ev);
return handled;
}
protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
synchronized(HorizontalListView.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 HorizontalListView.this.onDown(e);
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
getParent().requestDisallowInterceptTouchEvent(true);
synchronized(HorizontalListView.this){
mNextX += (int)distanceX;
}
requestLayout();
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Rect viewRect = new Rect();
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if(viewRect.contains((int)e.getX(), (int)e.getY())){
if(mOnItemClicked != null){
mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
break;
}
}
return true;
}
#Override
public void onLongPress(MotionEvent e) {
Rect viewRect = new Rect();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if (viewRect.contains((int) e.getX(), (int) e.getY())) {
if (mOnItemLongClicked != null) {
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
}
};
}
viewitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#fff">
<ImageView
android:id="#+id/image"
android:layout_width="145dp"
android:layout_height="145dp"
android:layout_marginTop="5dp"
android:scaleType="centerCrop"
android:src="#drawable/ic_launcher"
/>
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="text"
android:gravity="center_horizontal"
/>
</LinearLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:orientation="vertical" >
<com.horilistview.HorizontalListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ddd" />
</LinearLayout>
For example in this implementation you can use listSelector property in xml. Check out maybe yours also supports similar property or use the one I linked above.
public View selectedRow;//declare this in class
Add this code in onitemSelectListner
if (selectedRow != null) {
selectedRow.setBackgroundResource(color.transparent);
}
selectedRow = view; //view is the onitemSelectListner View
view.setBackgroundResource(R.drawable.list_background);
this will work 3.0 and above version..
add this onclick listener in getview method..
list.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
for(int j=0;j<20;j++)
{
test[j]=0;
}
for (int k = 0; k < mAdapter.getCount(); k++) {
View item = list.getChildAt(k);
if (item != null) {
test[k]=0;
item.setBackgroundColor(Color.WHITE);
}
view.setBackgroundColor(Color.BLUE);
test[i]=1;
}
}
test is a dummy array, use it out of onclicklistner to keep the selected even when view is changed.. like this..
if (test[position]==1) {
relativeLayout.setBackgroundColor(Color.BLUE);
}
if(test[position]==0)
relativeLayout.setBackgroundColor(Color.WHITE);
How to load dynamic images in custom ListView iI follow this tutorial to show ListView in horizontal http://www.dev-smart.com/archives/34 but the problem is this example used same sample icon,but I want to use dynamic images which I get from resource or web parsing
HorizontalListViewDemo.java :
public class HorizontalListViewDemo extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listviewdemo);
HorizontialListView listview = (HorizontialListView) findViewById(R.id.listview);
listview.setAdapter(mAdapter);
}
private static String[] dataObjects = new String[]{ "Text #1",
"Text #2",
"Text #3" };
private BaseAdapter mAdapter = new BaseAdapter() {
#Override
public int getCount() {
return dataObjects.length;
}
#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) {
View retval =
LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);
TextView title = (TextView) retval.findViewById(R.id.title);
title.setText(dataObjects[position]);
return retval;
}
};
}
Layout file :
<linearlayout xmlns:android="http://schemas.android.com/apk/res
/android" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff">
<com.devsmart.android.ui.horizontiallistview android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ddd">
</com.devsmart.android.ui.horizontiallistview>
</linearlayout>
<linearlayout xmlns:android="http://schemas.android.com
/apk/res/android" android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:background="#fff">
<imageview android:id="#+id/image"
android:layout_width="150dip"
android:layout_height="150dip"
android:scaletype="centerCrop"
android:src="#drawable/icon">
<textview android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textcolor="#000"
android:gravity="center_horizontal">
</textview></imageview></linearlayout>
HorizontalListView.java
public class HorizontalListView extends
AdapterView<ListAdapter> {
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<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;
public HorizontalListView(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(HorizontalListView.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 + child.getPaddingRight();
}
}
}
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(HorizontalListView.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 HorizontalListView.this.onDown(e);
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX,
velocityY);
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
synchronized(HorizontalListView.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(HorizontalListView.this, child, mLeftViewIndex + 1 +
i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.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(HorizontalListView.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());
}
};
}
Take a look at the link below. Someone already have written a library for it.
Android Universal Image Loader
I used this library in my recent projects and it worked flawlessly.
Hope it will help.
Here are those what you are looking for..
Android-lazy-image-loader-example.html
Loading-remote-images-in-a-listview-on-android/
As #Varundroid said you can make use of Android universal image loader, which works awesomely good. But that is a huge library for such a small purpose. You may consider writing your own Asynchronous Image Loader for Android ListView
You can change the following in your adapter class
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
NewsItem newsItem = (NewsItem) listData.get(position);
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getUrl());
}
return convertView;
}
For Downloading image in separate thread
class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference imageViewReference;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference(imageView);
}
#Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return downloadBitmap(params[0]);
}
#Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageDrawable(imageView.getContext().getResources()
.getDrawable(R.drawable.list_placeholder));
}
}
}
}
}
The above link has the complete tutorial for your purpose.
I have used lazy loading to download the images and thus populate in horizontal list view. But scrolling is not smooth, specially when scrolling from right to left end. These are my codes:
homepg.xml
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/Horizlistlatestnews"
android:layout_width="match_parent"
android:layout_height="105dp"
android:orientation="horizontal"
android:layout_below="#+id/Titlelatestnews"
>
<com.xxx.xxx.HorizontalView
android:id="#+id/horizontallistln"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:scrollbars="none"
>
</com.xxx.xxx.HorizontalView>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/Boxoffice"
android:layout_width="match_parent"
android:layout_height="145dp"
android:background="#drawable/bggray" >
<RelativeLayout
android:id="#+id/Titleboxofc"
android:layout_width="match_parent"
android:layout_height="30dp"
>
<TextView
android:id="#+id/textViewboxofc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BOX OFFICE"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:layout_alignParentLeft="true"
android:layout_marginLeft="5dp"
android:layout_centerVertical="true" />
<ProgressBar
android:id="#+id/progressBarboxofc"
android:layout_width="15dp"
android:layout_height="15dp"
android:visibility="gone"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/Horizlistboxofc"
android:layout_width="match_parent"
android:layout_height="105dp"
android:orientation="horizontal"
android:layout_below="#+id/Titleboxofc"
>
<com.xxx.xxx.HorizontalView
android:id="#+id/horizontallistbo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:scrollbars="none"
>
</com.xxx.xxx.HorizontalView>
</RelativeLayout>
</LinearLayout>
</ScrollView>
HorizontalView.java
package com.xxx.xxx;
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.Adapter;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;
public class HorizontalView extends AdapterView<Adapter> {
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 Adapter getAdapter() {
return mAdapter;
}
#Override
public View getSelectedView() {
return null;
}
#Override
public void setAdapter(Adapter adapter) {
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataObserver);
}
mAdapter = (ListAdapter) adapter;
mAdapter.registerDataSetObserver(mDataObserver);
reset();
}
private synchronized void reset() {
initView();
removeAllViewsInLayout();
requestLayout();
}
#Override
public void setSelection(int position) {
}
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,
(View) 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,
(View) mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, 0);
leftEdge -= child.getMeasuredWidth();
mLeftViewIndex--;
mDisplayOffset -= child.getMeasuredWidth();
}
}
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() {
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());
}
};
}
HorizontalImageAdapter.java
package com.xxx.xxx;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;
public class HorizontalImageAdapter extends ArrayAdapter<RSSItem> {
//private Context context;
private List<RSSItem> objectsln = new ArrayList<RSSItem>();
int ResourceId;
private Activity activity;
public ImageManager imageManager1;
private static ViewHolder holder;
public HorizontalImageAdapter(Activity a, int textViewResourceId, List<RSSItem> objectsln) {
super(a, textViewResourceId, objectsln);
System.out.println("LISTVIEW Constructor Called");
activity = a;
this.objectsln = objectsln;
this.ResourceId = textViewResourceId;
imageManager1 = new ImageManager(activity.getApplicationContext());
}
#Override
public int getCount() {
return this.objectsln.size();
}
#Override
public RSSItem getItem(int position) {
return this.objectsln.get(position);
}
#Override
public long getItemId(int position) {
System.out.println("LISTVIEW POSITION Called: "+position);
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater infleter = (LayoutInflater) this.getContext().getSystemService(Context.
LAYOUT_INFLATER_SERVICE);
convertView = infleter.inflate(ResourceId, parent, false);
holder = new ViewHolder();
holder.imageViewln = (ImageView) convertView.findViewById(R.id.imageViewhlist);
holder.textviewln=(TextView)convertView.findViewById(R.id.textViewhlist);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
RSSItem dataln = null ;
//get the item
if(objectsln.size() !=0){
dataln = getItem(position);
}else{
Log.i("test TAG", "Size zero found");
}
if (dataln != null) {
holder.textviewln.setText(dataln.title); // For taking the title from
// Web Services and set into text view
System.out.println("TITLE LATEST NEWS - "+position+": "+dataln.title);
holder.imageViewln.setScaleType(ScaleType.FIT_XY);
holder.imageViewln.setTag(dataln.imageurl);
imageManager1.displayImage(dataln.imageurl, activity,
holder.imageViewln);
}
return convertView;
}
private static class ViewHolder {
ImageView imageViewln;
TextView textviewln;
}
}