Android 如何制作水平ListView

Android 如何制作水平ListView,android,listview,horizontallist,Android,Listview,Horizontallist,我想制作一个水平列表视图,但我不想使用第三方的库。所以,我尝试使用PagerAdapter,但我能做到。 我不知道怎么修理它。 这是我用来加载照片的代码: public class GalleryActivity extends AppCompatActivity { public static final String TAG = "GalleryActivity"; public static final String EXTRA_NAME = "images"; ArrayList<

我想制作一个水平列表视图,但我不想使用第三方的库。所以,我尝试使用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;
    }
}
公共类GalleryActivity扩展了AppCompatActivity{
公共静态最终字符串TAG=“GalleryActivity”;
公共静态最终字符串EXTRA_NAME=“images”;
ArrayList actors=新的ArrayList();
专用GalleryPagerAdapter适配器;
@InjectView(R.id.pager)ViewPager\u pager;
@InjectView(R.id.缩略图)线性布局\u缩略图;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
注射(这个);
导入器();
_适配器=新GalleryPagerAdapter(此);
_寻呼机设置适配器(_适配器);
_pager.setOffscreenPageLimit(6);
}
公共无效导入器(){
位图Bitmap=BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.nhaphuong);
位图bitmap1=BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.subo);
位图bitmap2=BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.truonggiang);
演员=新演员(5,“NhãPhương”,位图);
演员1=新演员(15,“Trư”ờ吴江”,位图2);
Actor actor2=新的Actor(999,“Subo”,位图1);
添加(actor);
添加(actor1);
添加(actor2);
}
类GalleryPagerAdapter扩展PagerAdapter{
语境(Context)语境;;
充气机;
公共厨房页面编辑器(上下文){
_上下文=上下文;
_充气器=(LayoutInflater)\u context.getSystemService(context.LAYOUT\u充气器\u SERVICE);
}
@凌驾
public int getCount(){
返回actors.size();
}
@凌驾
公共布尔值isViewFromObject(视图,对象){
返回视图==((RelativeLayout)对象);
}
@凌驾
公共对象实例化项(视图组容器,最终int位置){
视图=\u充气器。充气(R.layout.one\u actor,container,false);
container.addView(视图);
//获取要在每个图像周围显示的边框大小
int borderSize=_缩略图。getPaddingTop();
//获取实际缩略图图像的大小
int thumbnailSize=((FrameLayout.LayoutParams)
_pager.getLayoutParams()).bottomMargin-(borderSize*2);
//设置缩略图布局参数。根据需要进行调整
LinearLayout.LayoutParams params=新的LinearLayout.LayoutParams(thumbnailSize,thumbnailSize);
参数设置边距(0,0,borderSize,0);
OneActor OneActor=新的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());
返回视图;
}
@凌驾
公共项(视图组容器、int位置、对象){
container.removeView((LinearLayout)对象);
}
第一类演员{
图像视图化身;
TextView名称,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>


请告诉我如何修复它或给我辅导!

最好使用RecyclerView。它还可以作为HorizontalListView使用,并且不需要任何第三方库。 为此,你需要这样做

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

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

最好使用RecyclerView。它还可以作为HorizontalListView使用,并且不需要任何第三方库。 为此,你需要这样做

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

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

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

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

};

}
import java.util.LinkedList;
导入java.util.Queue;
导入android.content.Context;
导入android.database.DataSetObserver;
导入android.graphics.Rect;
导入android.util.AttributeSet;
导入android.util.Log;
导入android.view.GestureDetector;
导入android.view.GestureDetector.OnTestureListener;
导入android.view.MotionEvent;
导入android.view.view;
导入android.widget.AdapterView;
导入android.widget.ListAdapter;
导入android.widget.Scroller;
公共类HorizontalListView扩展了AdapterView{
公共布尔值mAlwaysOverrideTouch=true;
保护列表适配器mAdapter;
private int mLeftViewIndex=-1;
private int mRightViewIndex=0;
受保护的int-mCurrentX;
受保护的int mNextX;
private int mMaxX=Integer.MAX_值;
私有整数mDisplayOffset=0;
保护滚轮;
私人手势;
私有队列mRemovedViewQueue=新链接列表();
private OnItemSelectedListener监视项Selected;
私有监听监听监听项被点击;
公共水平列表视图(上下文、属性集属性){
超级(上下文,attrs);
initView();
}
私有void initView(){
mLeftViewIndex=-1;
mRightViewIndex=0;
mDisplayOffset=0;
mCurrentX=0;
mNextX=0;
mMaxX=整数的最大值;
mScroller=新滚动条(getContext());
mGesture=新的手势检测器(getContext(),mOnGesture);
}
@凌驾
公共无效setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener){
mOnItemSelected=侦听器;
Log.v(“Log_标签”,“点击时设置消息”);
}
@凌驾
public void setOnItemClickListener(AdapterView.OnItemClickListener侦听器){
mOnItemClicked=侦听器;
Log.v(“Log_标签”,“点击项目设置”);
}
私有DataSetoObserver mDataObserver=新DataSetoObserver(){
@重写公共void onChanged(){
//TODO自动生成的方法存根
super.onChanged();}
@覆盖公共