如何制作水平ListView

时间:2016-03-10 09:19:34

标签: android listview horizontallist

我想制作一个水平列表视图,但我不想使用第三方库。所以,我尝试使用PagerAdapter,但我可以做到。 我不知道如何解决它。 这是我用来加载照片的代码:

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;
    }
}

这是我的xml文件:

<?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>

告诉我如何解决它或给我一个好消息!

2 个答案:

答案 0 :(得分:1)

最好使用RecyclerView。它也可以作为Horizo​​ntalListView使用,它不需要任何第三方库。 为此你需要做这样的事情

LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);

答案 1 :(得分:1)

如果您不必使用它,则必须使用RecyclerView,然后使用Horizo​​ntalListView。请参阅下面的Horizo​​ntalListView代码

<强> Horizo​​ntalListView.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;}

};

}

在xml中用作listview,如

<youpackage.HorizantalListView
 android:layout_width="match_parent"
android:layout_height="match_parent"/>