標籤:
轉載請標明出處:
http://blog.csdn.net/hai_qing_xu_kong/article/details/52186398
本文出自:【顧林海的部落格】
前言
已經好長時間沒更新部落格了,今天給大家帶來一個橫向滾動的菜單,用的是HorizontalScrollView,但HorizontalScrollView不能在滾動時定位到某個菜單,因此監聽了onScrollChanged方法,代碼比較簡單,大家看代碼就行了,主要是封裝了一下,方便大家使用,項目github在底部會給出的。廢話不多說,先上:
怎麼用
這個控制項已經進行了非常給力的封裝了,想必大家一定用的比較酸爽。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.horizontalscrollview.view.HorizontalScrollMenuView android:id="@+id/hs_menu" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:layout_centerVertical="true"/></RelativeLayout>
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<View> mMenuArray=new SparseArray<>(); /** * 擷取子View的寬度,必傳 * @return */ public abstract int getViewWidth(); public SparseArray<View> getView(){ mMenuArray.clear(); for(int index=0,length=getCount();index<length;index++){ mMenuArray.append(index,getView(index)); } return mMenuArray; }}
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<View> viewSparseArray=mBaseMenuAdapter.getView(); View intervalView; for(int index=0,length=viewSparseArray.size();index<length;index++){ if (index == 0) { /** * <p> * 在最左邊增加一個(屏寬-菜單寬)/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) { /** * <p> * 在最右邊增加一個(屏寬-菜單寬)/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-裝B必備自訂View(1)