Android之自定义横向滚动菜单

转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/52186398
本文出自:【顾林海的博客】

##前言

已经好长时间没更新博客了,今天给大家带来一个横向滚动的菜单,用的是HorizontalScrollView,但HorizontalScrollView不能在滚动时定位到某个菜单,因此监听了onScrollChanged方法,代码比较简单,大家看代码就行了,主要是封装了一下,方便大家使用,项目github在底部会给出的。废话不多说,先上效果图:

##怎么用

这个控件已经进行了非常给力的封装了,想必大家一定用的比较酸爽。

Android之自定义横向滚动菜单_第1张图片




    




package com.horizontalscrollview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.horizontalscrollview.view.HorizontalScrollMenuView;
import com.horizontalscrollview.view.adapter.BaseMenuAdapter;

public class MainActivity extends AppCompatActivity {

    private int[] mDrawableId={R.drawable.image1,R.drawable.image3,R.drawable.image3};
    private String[] mTitle={"菜单一","菜单二","菜单三"};

    private HorizontalScrollMenuView mHorizontalScrollMenuView;
    private MyMenuAdapter mMyMenuAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private void initViews(){
        mHorizontalScrollMenuView= (HorizontalScrollMenuView) findViewById(R.id.hs_menu);
        mMyMenuAdapter=new MyMenuAdapter();
        mHorizontalScrollMenuView.setAdapter(mMyMenuAdapter);
        mHorizontalScrollMenuView.notifyDataSetChanged();
    }


    class MyMenuAdapter extends BaseMenuAdapter{
        @Override
        public int getCount() {
            return mTitle.length;
        }

        @Override
        public View getView(final int position) {
            View root= LayoutInflater.from(MainActivity.this).inflate(R.layout.menu_layout,null);
            ImageView imageView= (ImageView) root.findViewById(R.id.iv_icon);
            TextView tv_title= (TextView) root.findViewById(R.id.tv_title);
            tv_title.setText(mTitle[position]);
            imageView.setImageResource(mDrawableId[position]);
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this,"点击了"+mTitle[position],Toast.LENGTH_SHORT).show();
                }
            });
            return root;
        }

        @Override
        public int getViewWidth() {
            return 250;
        }
    }


}

用法已经贴出来了,下面有兴趣的话看看源码,没兴趣的话,我也没辙,呵呵。。。

##装B源码

package com.horizontalscrollview.view.adapter;

import android.view.View;

/**
 * Created by glh on 2016-08-11.
 */
public interface MenuAdapter {
    int getCount();
    View getView(int position);
}

package com.horizontalscrollview.view.adapter;

import android.util.SparseArray;
import android.view.View;

/**
 * 菜单的抽象类,用户子菜单View的保存
 * Created by glh on 2016-08-11.
 */
public abstract class BaseMenuAdapter implements MenuAdapter{

    private SparseArray mMenuArray=new SparseArray<>();

    /**
     * 获取子View的宽度,必传
     * @return
     */
    public abstract int getViewWidth();

    public SparseArray getView(){
        mMenuArray.clear();
        for(int index=0,length=getCount();index
package com.horizontalscrollview.view;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.horizontalscrollview.R;
import com.horizontalscrollview.util.DensityUtil;
import com.horizontalscrollview.view.adapter.BaseMenuAdapter;

/**
 * 水平滚动的菜单
 * Created by glh on 2016-08-11.
 */
public class HorizontalScrollMenuView extends RelativeLayout{

    private Context mContext;

    private View mRootView;
    private LinearLayout ll_menu;//菜单容器
    private ObservableHorizontalScrollView mObservableHorizontalScrollView;//滚动容器
    private int mMenuIndex;
    private int mScroll;
    private int interval;//菜单最左边和最右边的距离
    private int mMiddle;//菜单间隔距离
    private int mViewWidth;//菜单宽度
    private MyHandler mMyHandler;
    private BaseMenuAdapter mBaseMenuAdapter;

    public HorizontalScrollMenuView(Context context) {
        this(context, null);

    }

    public HorizontalScrollMenuView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HorizontalScrollMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext=context;
        mMyHandler=new MyHandler();
        interval=(DensityUtil.getWindowWidth(mContext) - DensityUtil.dip2px(250)) / 2;
        mMiddle=DensityUtil.dip2px(25);
        mViewWidth=DensityUtil.dip2px(250);
        initView();
        initEvent();
    }

    private void initView(){
        mRootView= LayoutInflater.from(mContext).inflate(R.layout.horizontal_scroll_layout,this,true);
        ll_menu= (LinearLayout) mRootView.findViewById(R.id.ll_menu);
        mObservableHorizontalScrollView= (ObservableHorizontalScrollView) mRootView.findViewById(R.id.obh_view);
    }

    /**
     * 添加菜单
     */
    private void addMenu(){
        ll_menu.removeAllViews();
        SparseArray viewSparseArray=mBaseMenuAdapter.getView();
        View intervalView;
        for(int index=0,length=viewSparseArray.size();index
                 *     在最左边增加一个(屏宽-菜单宽)/2的宽度的View,
                 *     目的在于使第一个菜单居中显示。
                 * 
                 */
                intervalView = new View(mContext);
                intervalView.setLayoutParams(new LayoutParams(interval, 1));
                ll_menu.addView(intervalView);
            }
            ll_menu.addView(viewSparseArray.get(index));
            if (index == length-1) {
                /**
                 * 

* 在最右边增加一个(屏宽-菜单宽)/2的宽度的View, * 目的在于使最后一个菜单居中显示。 * */ intervalView = new View(mContext); intervalView.setLayoutParams(new LayoutParams(interval, 1)); ll_menu.addView(intervalView); }else{ /** * 两个菜单之间留一点空隙 */ intervalView = new View(mContext); intervalView.setLayoutParams(new LayoutParams(mMiddle, 1)); ll_menu.addView(intervalView); } } } private void initEvent(){ mObservableHorizontalScrollView.setHorizontalScrollViewListener(new ObservableHorizontalScrollView.HorizontalScrollViewListener() { @Override public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldx, int oldy) { mMenuIndex = x / mViewWidth;//计算当前位置 mScroll = x % mViewWidth; if (mScroll >= 0.5) { mMenuIndex++; } if (oldx - x > 0) { /** * 菜单往右滑动 */ mMenuIndex--; } } }); mObservableHorizontalScrollView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: mMyHandler.sendEmptyMessage(0); break; default: break; } return false; } }); } /** * 设置View * @param adapter */ public void setAdapter(BaseMenuAdapter adapter){ this.mBaseMenuAdapter=adapter; this.interval =(DensityUtil.getWindowWidth(mContext) - DensityUtil.dip2px(mBaseMenuAdapter.getViewWidth())) / 2; this.mViewWidth=DensityUtil.dip2px(mBaseMenuAdapter.getViewWidth()); } /** * 刷新 */ public void notifyDataSetChanged(){ addMenu(); } /** * 设置菜单间隔 * @param middle */ public void setMiddle(int middle){ mMiddle=DensityUtil.dip2px(middle); } class MyHandler extends Handler { public MyHandler() { } @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: mObservableHorizontalScrollView.smoothScrollTo(mMenuIndex * (mViewWidth + mMiddle), 0); break; } } } }

##项目地址(豪华套餐)

以下是完整的github项目地址
github项目源码地址:点击【项目源码】

你可能感兴趣的:([,Android自定义控件,],Android开发笔记)