Android自定义横向滑动菜单的实现

本文讲述了Android自定义横向滑动菜单的实现。分享给大家供大家参考,具体如下:

前言

开发安卓过程中,经常会用到标题栏的样式,有时候传统方式不能满足开发者的需要,这时候就需要自定义控件来实现。(注意:本文提供思路,有关键代码,但是代码不全)

标题栏说明

自定义标题栏ColumnHorizontalScrollView继承HorizontalScrollView 这个安卓原生的控件,HorizontalScrollView是一种FrameLayout(框架布局),其子项被滚动查看时是整体移动的,并且子项本身可以是一个有复杂层次结构的布局管理器。一个常见的应用是子项在水平方向中,用户可以滚动显示顶层水平排列的子项(items)。

在布局文件中添加ColumnHorizontalScrollView控件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tabs="http://schemas.android.com/apk/res-auto"
 android:id="@+id/homeTabs"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="@color/db_bg_gray"
 android:orientation="vertical">
 <com.wankr.app.widget.ColumnHorizontalScrollView
     android:id="@+id/mColumnHorizontalScrollView"
  android:layout_height="match_parent"
  android:layout_width="wrap_content"
  android:layout_centerVertical="true"
  android:scrollbars="none">
  <LinearLayout
   android:id="@+id/mRadioGroup_content"
   android:layout_width="fill_parent"
   android:layout_height="match_parent"
   android:layout_centerVertical="true"
   android:gravity="center_vertical"
   android:orientation="horizontal"
   android:paddingLeft="10.0dip"
   android:paddingRight="10.0dip" />
 </com.wankr.app.widget.ColumnHorizontalScrollView>
 <android.support.v4.view.ViewPager
   android:id="@+id/contentPager"
   android:layout_width="match_parent"
   android:layout_height="0dp"
   android:layout_weight="1" />
</LinearLayout>

横向菜单中展示界面
注意:可以设置菜单中标题的宽度大小,最好标题宽度一致。

package com.example.app;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.LayoutParams;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Fragment implements OnClickListener {
 private ViewPager contentPager;
 private ContentPagerAdapter pagerAdapter;
 private ColumnHorizontalScrollView mColumnHorizontalScrollView;
 private LinearLayout mRadioGroup_content;
 /** 请求CODE */
 public final static int CHANNELREQUEST = 1;
 /** 屏幕宽度 */
 private int mScreenWidth = 0;
 /** Item宽度 */
 private int mItemWidth = 0;
 /** 当前选中的栏目*/
 private int columnSelectIndex = 0;
 // 标签信息
 private List<ChannelItem> channelItems = new ArrayList<ChannelItem>();
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View v = inflater.inflate(R.layout.activity_main, container , false);
  this.contentPager = (ViewPager) v.findViewById(R.id.contentPager);
  this.pagerAdapter = new ContentPagerAdapter(getChildFragmentManager());
  this.contentPager.setAdapter(this.pagerAdapter);
  this.contentPager.setCurrentItem(0);
  this.contentPager.setOnPageChangeListener(pageListener);
  this.mColumnHorizontalScrollView = (ColumnHorizontalScrollView) v.findViewById(R.id.mColumnHorizontalScrollView);
  this.mRadioGroup_content = (LinearLayout) v.findViewById(R.id.mRadioGroup_content);
  this.setChangeView();
  return v;
 }
 /**
  * 设置标题适配器
  * @author raotaisen
  *
  */
 private class ContentPagerAdapter extends FragmentPagerAdapter {
  public ContentPagerAdapter(FragmentManager fm) {
   super(fm);
   // TODO Auto-generated constructor stub
  }
  @Override
  public Fragment getItem(int arg0) {
   // TODO Auto-generated method stub
   return null;
  }
  @Override
  public int getCount() {
   // TODO Auto-generated method stub
   return channelItems.size();
  }
  /**
   * 标题设置
   */
  @Override
  public CharSequence getPageTitle(int position) {
   ChannelItem item = channelItems.get(position);
   return item.getChanneName();
  }
 }
 /**
  * ViewPager切换监听方法
  * */
 public ViewPager.OnPageChangeListener pageListener= new ViewPager.OnPageChangeListener(){
  @Override
  public void onPageScrollStateChanged(int arg0) {
  }
  @Override
  public void onPageScrolled(int arg0, float arg1, int arg2) {
  }
  @Override
  public void onPageSelected(int position) {
   contentPager.setCurrentItem(position);
   selectTab(position);
  }
 };
 /**
  * 选择的Column里面的Tab
  * */
 private void selectTab(int tab_postion) {
  columnSelectIndex = tab_postion;
  for (int i = 0; i < mRadioGroup_content.getChildCount(); i++) {
   View checkView = mRadioGroup_content.getChildAt(tab_postion);
   int k = checkView.getMeasuredWidth();
   int l = checkView.getLeft();
   int i2 = l + k / 2 - mScreenWidth / 2;
   // rg_nav_content.getParent()).smoothScrollTo(i2, 0);
   mColumnHorizontalScrollView.smoothScrollTo(i2, 0);
   // mColumnHorizontalScrollView.smoothScrollTo((position - 2) *
   // mItemWidth , 0);
  }
  //判断是否选中
  for (int j = 0; j < mRadioGroup_content.getChildCount(); j++) {
   View checkView = mRadioGroup_content.getChildAt(j);
   boolean ischeck;
   if (j == tab_postion) {
    ischeck = true;
   } else {
    ischeck = false;
   }
   checkView.setSelected(ischeck);
  }
  // 指向对应的tab位置
  switch (tab_postion) {
  }
 }
 /**
  * 当栏目项发生变化时候调用
  */
 private void setChangeView() {
  gettColumnData();
  initTabColumn();
 }
 /**
  * 获取标签栏数据
  */
 private void gettColumnData() {
  channelItems.clear();
  channelItems.add(new ChannelItem(null, "葱葱"));
  channelItems.add(new ChannelItem(null, "飞飞"));
  channelItems.add(new ChannelItem(null, "vv"));
  channelItems.add(new ChannelItem(null, "刚子"));
  channelItems.add(new ChannelItem(null, "最新"));
  /**
   * 标题可以动态设置长度。获取数据添加到集合中展示。
   */
  pagerAdapter.notifyDataSetChanged();
 }
 /**
  *初始化Column栏目项
  */
 private void initTabColumn() {
  mRadioGroup_content.removeAllViews();
  int count = channelItems.size();
  // 设置横向菜单栏中item属性
  mColumnHorizontalScrollView.setParam(getActivity(), mScreenWidth, mRadioGroup_content, null, null, null, null);
  for(int i = 0; i< count; i++){
   LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT , LayoutParams.WRAP_CONTENT);
   params.leftMargin = 6;
   params.rightMargin = 6;
//   TextView localTextView = (TextView) mInflater.inflate(R.layout.column_radio_item, null);
   TextView columnTextView = new TextView(getActivity());
   columnTextView.setTextSize(16);
   columnTextView.setGravity(Gravity.CENTER);
   columnTextView.setPadding(5, 5, 5, 5);
   columnTextView.setId(i);
   columnTextView.setText(channelItems.get(i).getChanneName());
//   columnTextView.setTextColor(getResources().getColorStateList(R.color.top_category_scroll_text_color_day));
   if(columnSelectIndex == i){
    columnTextView.setSelected(true);
   }
   // 对item的监听
   columnTextView.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
     for(int i = 0;i < mRadioGroup_content.getChildCount();i++){
      View localView = mRadioGroup_content.getChildAt(i);
      if (localView != v) {
       localView.setSelected(false);
      }else{
       localView.setSelected(true);
       contentPager.setCurrentItem(i);
      }
     }
//     Toast.makeText(getApplicationContext(), userChannelList.get(v.getId()).getName(), Toast.LENGTH_SHORT).show();
    }
   });
   mRadioGroup_content.addView(columnTextView, i ,params);
  }
 }
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
 }

}

标题菜单横向滑动自定义控件

package com.example.app;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
public class ColumnHorizontalScrollView extends HorizontalScrollView {
 /** 传入整体布局 */
 private View ll_content;
 /** 传入更多栏目选择布局 */
 private View ll_more;
 /** 传入拖动栏布局 */
 private View rl_column;
 /** 左阴影图片 */
 private ImageView leftImage;
 /** 右阴影图片 */
 private ImageView rightImage;
 /** 屏幕宽度 */
 private int mScreenWitdh = 0;
 /** 父类的活动activity */
 private Activity activity;
 public ColumnHorizontalScrollView(Context context) {
  super(context);
 }
 public ColumnHorizontalScrollView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 public ColumnHorizontalScrollView(Context context, AttributeSet attrs,
          int defStyle) {
  super(context, attrs, defStyle);
 }
 /**
  * 在拖动的时候执行
  * */
 @Override
 protected void onScrollChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
  // TODO Auto-generated method stub
  super.onScrollChanged(paramInt1, paramInt2, paramInt3, paramInt4);
  shade_ShowOrHide();
  if(!activity.isFinishing() && ll_content !=null && leftImage!=null && rightImage!=null && ll_more!=null && rl_column !=null){
   if(ll_content.getWidth() <= mScreenWitdh){
    leftImage.setVisibility(View.GONE);
    rightImage.setVisibility(View.GONE);
   }
  }else{
   return;
  }
  if(paramInt1 ==0){
   leftImage.setVisibility(View.GONE);
   rightImage.setVisibility(View.VISIBLE);
   return;
  }
  if(ll_content.getWidth() - paramInt1 + ll_more.getWidth() + rl_column.getLeft() == mScreenWitdh){
   leftImage.setVisibility(View.VISIBLE);
   rightImage.setVisibility(View.GONE);
   return;
  }
  leftImage.setVisibility(View.VISIBLE);
  rightImage.setVisibility(View.VISIBLE);
 }
 /**
  * 传入父类布局中的资源文件
  * */
 public void setParam(Activity activity, int mScreenWitdh,View paramView1,ImageView paramView2, ImageView paramView3 ,View paramView4,View paramView5){
  this.activity = activity;
  this.mScreenWitdh = mScreenWitdh;
  ll_content = paramView1;
  leftImage = paramView2;
  rightImage = paramView3;
  ll_more = paramView4;
  rl_column = paramView5;
 }
 /**
  * 判断左右阴影的显示隐藏效果
  * */
 public void shade_ShowOrHide() {
  if (!activity.isFinishing() && ll_content != null) {
   measure(0, 0);
   //如果整体宽度小于屏幕宽度的话,那左右阴影都隐藏
   if (mScreenWitdh >= getMeasuredWidth()) {
    leftImage.setVisibility(View.GONE);
    rightImage.setVisibility(View.GONE);
   }
  } else {
   return;
  }
  //如果滑动在最左边时候,左边阴影隐藏,右边显示
  if (getLeft() == 0) {
   leftImage.setVisibility(View.GONE);
   rightImage.setVisibility(View.VISIBLE);
   return;
  }
  //如果滑动在最右边时候,左边阴影显示,右边隐藏
  if (getRight() == getMeasuredWidth() - mScreenWitdh) {
   leftImage.setVisibility(View.VISIBLE);
   rightImage.setVisibility(View.GONE);
   return;
  }
  //否则,说明在中间位置,左、右阴影都显示
  leftImage.setVisibility(View.VISIBLE);
  rightImage.setVisibility(View.VISIBLE);
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android程序开发之使用Design包实现QQ动画侧滑效果和滑动菜单导航

    Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件.最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2.这不得不说是一个良心之作. 使用方法很简单,只需要添加一句依赖 compile 'com.android

  • Android利用滑动菜单框架实现滑动菜单效果

    之前我向大家介绍了史上最简单的滑动菜单的实现方式,相信大家都还记得.如果忘记了其中的实现原理或者还没看过的朋友,请先去看一遍之前的文章Android仿人人客户端滑动菜单的侧滑特效实现代码,史上最简单的侧滑实现 ,因为我们今天要实现的滑动菜单框架也是基于同样的原理的. 之前的文章中在最后也提到了,如果是你的应用程序中有很多个Activity都需要加入滑动菜单的功能,那么每个Activity都要写上百行的代码才能实现效果,再简单的滑动菜单实现方案也没用.因此我们今天要实现一个滑动菜单的框架,然后在任

  • Android 3D滑动菜单完全解析 Android实现推拉门式的立体特效

    在上一篇文章中,我们学习了Camera的基本用法,并借助它们编写了一个例子,实现了类似于API Demos里的图片中轴旋转功能.不过那个例子的核心代码是来自于API Demos中带有的Rotate3dAnimation这个类,是它帮助我们完成了所有的三维旋转操作,所有Matrix和Camera相关的代码也是封装在这个类中. 这样说来的话,大家心里会不会痒痒的呢?虽然学习了Camera的用法,但却没有按照自己的理解来实现一套非常炫酷的3D效果.不要着急,今天我就带着大家一起来实现一种3D推拉门式的

  • Android Studio使用ViewPager+Fragment实现滑动菜单Tab效果

    本文为大家分享了Android Studio实现滑动菜单Tab效果的具体代码,供大家参考,具体内容如下 描述: 之前有做过一个记账本APP,拿来练手的,做的很简单,是用Eclipse开发的: 最近想把这个APP重新完善一下,添加了一些新的功能,并选用Android Studio来开发: APP已经完善了一部分,现在就想把已经做好的功能整理一下,记录下来. 效果图: 可以手动滑动菜单 也可以通过点击头部菜单进行切换 具体实现的代码: 前台代码(activity_main.xml): <?xml v

  • Android模仿美团顶部的滑动菜单实例代码

    前言 本文主要给大家介绍了关于Android模仿美团顶部滑动菜单的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 先来看下效果图: 实现方法 这是通过 ViewPager 和 GridView 相结合做出来的效果,每一个 ViewPager 页面都是一个 GridView,底部的每个滑动指示圆点都是从布局文件中 inflate 出来的 首先需要一个代表每个活动主题的 JavaBean /** * Created by CZY on 2017/6/23. */ publ

  • Android实现3D推拉门式滑动菜单源码解析

    前言   又看了郭霖大神的一篇博客<Android 3D滑动菜单完全解析,实现推拉门式的立体特效>,是关于自定义控件方面的,因为自己关于自定义控件了解的不过,以前的要求是会用就行,但是后来越发的明白只会用是不够的,出现问题都不知道该怎么分析,所以我才打算把别人博客里的自定义控件的源码给看懂,虽然可能时间花的时间长,但是,绝对是值得的!   因为源码的东西比较多,看完之后发现还存在可以优化的地方,郭神的代码当时是为了例子讲解,所以对这个控件类的封装就没有仔细去做,所以我就进行了封装和优化,是的移

  • Android仿人人客户端滑动菜单的侧滑菜单效果

    人人客户端有一个特效还是挺吸引人的,在主界面手指向右滑动,就可以将菜单展示出来,而主界面会被隐藏大部分,但是仍有左侧的一小部分同菜单一起展示. 据说人人客户端的这个特效是从facebook客户端模仿来的,至于facebook是不是又从其它地方模仿来的就不得而知了.好,今天我们就一起来实现这个效果,总之我第一次看到这个特效是在人人客户端看到的,我也就主观性地认为我是在模仿人人客户端的特效了. 虽然现在网上类似这种效果的实现也非常多,可是我发现实现方案大都非常复杂,并不容易理解.但其实这种效果并不难

  • Android自定义横向滑动菜单的实现

    本文讲述了Android自定义横向滑动菜单的实现.分享给大家供大家参考,具体如下: 前言 开发安卓过程中,经常会用到标题栏的样式,有时候传统方式不能满足开发者的需要,这时候就需要自定义控件来实现.(注意:本文提供思路,有关键代码,但是代码不全) 标题栏说明 自定义标题栏ColumnHorizontalScrollView继承HorizontalScrollView 这个安卓原生的控件,HorizontalScrollView是一种FrameLayout(框架布局),其子项被滚动查看时是整体移动的

  • Android实现横向二级菜单

    本文实例为大家分享了Android二级横向菜单的实现过程.效果如上图: 这种横向的二级菜单在很多的app都有所应用.效果看起来还是非常的美观的.也算是项目需要,自己也就学了一下这个效果,首先说一下逻辑.实现的方式其实并不是很难..只不过逻辑上可能有点复杂.原理其实就是一个按钮.当触发按钮的时候弹出PopWindow.PopWindow由两个ListView构成..对两个ListView适当的适配.就可以实现这个效果了.. 实现这种效果可以有两种不同的方式..一种是直接在布局文件layout.xm

  • Android自定义实现侧滑菜单效果

    本文实例为大家分享了Android自定义实现侧滑菜单的具体代码,供大家参考,具体内容如下 实现原理:继承ViewGroup控件要显示到界面上需要重写OnMeature() OnLayout(),因此在实现OnLayout()的时候,将菜单界面划出到屏幕左侧,动态改变菜单界面距离scrollXto()左边界的距离就能实现滑动效果. 1.继承ViewGroup 2.事件分发机制 3.状态监听 在主界面中添加两个子控件 <com.oblivion.ui.SlideMenu xmlns:android=

  • jquery实现仿Flash的横向滑动菜单效果代码

    本文实例讲述了jquery实现仿Flash的横向滑动菜单效果代码.分享给大家供大家参考.具体如下: 这是一个仿Flash的jquery滑动菜单,横向,延时效果明显,如果觉得延时太长的话,自己可以修改参数,通过这个菜单主要是想向大家掌握一些jQuery生成动画的技巧,同时这也是jquery强大功能的体现. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/jquery-f-flash-style-move-menu-codes/ 具体代码如下: <!

  • Android 自定义弹出菜单和对话框功能实例代码

    Android 开发当中,可能会存在许多自定义布局的需求,比如自定义弹出菜单(popupWindow),以及自定义对话框(Dialog). 话不多说,直接上图片. 先讲第一种,自定义PopUpWindow 1.popupWindow protected void showPopWindow(View view, final int pos){ WindowManager wm= (WindowManager) myContext.getSystemService(Context.WINDOW_S

  • Android自定义View展开菜单功能的实现

    先给大家展示下效果图,如果大家感觉不错,请参考实现代码. 思路 1.下角Button的父View加入一个FrameLayout,也就是图中全屏透明灰色部分. 菜单没有弹出的时候设置为不可见. 设置FrameLayout点击事件,点击的时候缩回菜单. 对应init() 2.rameLayout中加入菜单按钮,也就是弹出的那三个. 菜单没有弹出的时候设置为不可见. 对应addElement()和freshElement() 3.右下角的按钮,旋转图标(也可以不旋转). 对应setRotateAnim

  • Android自定义FloatingActionButton滑动行为只隐藏不出现的问题小结

    先来段Behavior代码,网上关于FloatingActionButton(以下简称FAB)滑动的代码很多了,参考一下. public class FabBehavior extends FloatingActionButton.Behavior{ private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private boolean mIsAnimatingOut = false; p

  • Android自定义日历滑动控件

    本文实例为大家分享了Android自定义日历滑动控件的使用方法,供大家参考,具体内容如下 最近公司项目需要做这个需求,自己才疏学浅,总算能写出个大概来,遂在这里记录下来. 分析 先来分析一下: 首先,我们的需求是可以左右点击查看跳转到下一个月,中间的日历控件可以水平滚动选择日期,所以我们中间的日历控件用一个RecycleView来做,左右两位的为ImageVeiw. LRCalendarView 总体流程: 编写LRCalendarView的布局R.layout.calendar_view 新建

  • Android自定义Seekbar滑动条 Pop提示跟随滑动按钮滑动

    本文实例为大家分享了Android自定义Seekbar滑动条的具体代码,供大家参考,具体内容如下 由于项目需要做出此效果,自定义写了一个. 效果图 思路: 原始的seekbar只有滑动条并没有下方的提示文字,所以我们必须要继承Seekbar重写这个控件. 代码: 在values文件夹下新建attrs.xml,用于设置跟随滑动按钮的文字大小,颜色,背景. <declare-styleable name="MySeekBar"> <attr name="text

  • Android实现左侧滑动菜单

    本文实例为大家分享了Android实现左侧滑动菜单的具体代码,供大家参考,具体内容如下 效果图: SlideActivity.java: package com.demo.slide;   import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.Window;   import com.demo.broadcast.R;   public class

随机推荐