Android--HorizontalListView实现横向滑动

原理:继承AdapterView构造的HorizontalListView

效果图:

 

下面看源码:

这是Activity的布局文件:activity_main.xml


        
        
        
        
    

横向listview的每个item的布局




    

month_seltctor.xml




    
        
            
            
        
    
    
        
            
            
        
    

主程序:MainActivity.java

public class meterRateActivity extends Activity {
    private final static String TAG = meterRateActivity.class.getName();
    private meterrateAdapter mMeterrateAdapter;
    private HorizontalListViewAdapter hListViewAdapter;
    private View olderSelectView = null;


    @BindView(R.id.iv_return)
    ImageView ivReturn;
    @BindView(R.id.sp_year)
    Spinner spYear;
    @BindView(R.id.tv_total)
    TextView tvTotal;
    @BindView(R.id.tv_reality)
    TextView tvReality;
    @BindView(R.id.tv_incomplete)
    TextView tvIncomplete;
    @BindView(R.id.tv_rate)
    TextView tvRate;
    @BindView(R.id.rv_workrate)
    RecyclerView rvWorkrate;
    @BindView(R.id.hl_month)
    HorizontalListView hlMonth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_meterrate);
        ButterKnife.bind(this);

        initData();
    }


    private void initData() {
        //years
        List years = new ArrayList<>();
        int year = Integer.parseInt(timeUtils.getyear());
        for (int i = year - 10; i <= year + 10; i++) {
            years.add(i);
        }
        ArrayAdapter adapter = new ArrayAdapter<>(meterRateActivity.this,
                android.R.layout.simple_list_item_1, years);
        spYear.setAdapter(adapter);
        int position = adapter.getPosition(year);
        spYear.setSelection(position, true);

        //months
        String[] months = {"1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"};
        hListViewAdapter = new HorizontalListViewAdapter(getApplicationContext(),months);
        hlMonth.setAdapter(hListViewAdapter);
        hlMonth.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                hListViewAdapter.setSelectIndex(position);
                hListViewAdapter.notifyDataSetChanged();
            }
        });
    }

    @OnClick({R.id.iv_return, R.id.tv_total, R.id.tv_reality, R.id.tv_incomplete, R.id.tv_rate})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_return:
                startActivity(new Intent(meterRateActivity.this, HomeActivity.class));
                finish();
                break;
            case R.id.tv_total:
                break;
            case R.id.tv_reality:
                break;
            case R.id.tv_incomplete:
                break;
            case R.id.tv_rate:
                break;
        }
    }
}

HorizontalListView.java 这就是自定义的横向listview

package view;

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;

/**
 * Created by Administrator on 2019/5/23
 * 

* desc:横向滑动 */ public class HorizontalListView extends AdapterView{ public boolean mAlwaysOverrideTouch = true; protected ListAdapter mAdapter; private int mLeftViewIndex = -1; private int mRightViewIndex = 0; protected int mCurrentX; protected int mNextX; private int mMaxX = Integer.MAX_VALUE; private int mDisplayOffset = 0; protected Scroller mScroller; private GestureDetector mGesture; private Queue mRemovedViewQueue = new LinkedList(); private OnItemSelectedListener mOnItemSelected; private OnItemClickListener mOnItemClicked; private OnItemLongClickListener mOnItemLongClicked; private boolean mDataChanged = false; public 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

HorizontalListViewAdapter.java 横向listview的适配器

package adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.water.R;

/**
 * Created by Administrator on 2019/5/23
 * 

* desc:月份水平滑动适配 */ public class HorizontalListViewAdapter extends BaseAdapter { private String[] mMonth; private Context mContext; private LayoutInflater mInflater; private int selectIndex = -1; public HorizontalListViewAdapter(Context context, String[] month) { this.mContext = context; this.mMonth = month; mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//LayoutInflater.from(mContext); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.item_month, null); holder.mMonth = (TextView) convertView.findViewById(R.id.tv_month); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } if (position == selectIndex) { convertView.setSelected(true); } else { convertView.setSelected(false); } holder.mMonth.setText(mMonth[position]); return convertView; } @Override public int getCount() { return mMonth.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } private static class ViewHolder { private TextView mMonth ; } public void setSelectIndex(int i){ selectIndex = i; } }

 

你可能感兴趣的:(Android,Android开发,横向滑动,水平滑动,listview,Android)