`

顶部横向滑动菜单效果

阅读更多
这个是在在别人的基础上改的(基本上没改),我就不重造轮子了。

先是自定义的横向ScollView,用Adapter模式填充数据
import com.example.demo.R;

import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class NavigationHorizontalScrollView extends HorizontalScrollView implements OnClickListener {

	public NavigationHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public NavigationHorizontalScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public NavigationHorizontalScrollView(Context context) {
		super(context);
		init();
	}

	private FrameLayout mFrameLayout;
	private BaseAdapter mBaseAdapter;
	private SparseArray<View> mSparseArray;
	private int oldPosition;
	private TextView backView;
	private ImageView preImage, nextImage;

	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		resetImageView();
	}

	private void resetImageView() {
		/* 计算水平方向滚动条的滑块的偏移值。 */
		int ScrollOffset = computeHorizontalScrollOffset();
		/* 滚动条长度 */
		int ScrollExtent = computeHorizontalScrollExtent();
		/* 滚动条当前位置 */
		int curScrollLoc = ScrollOffset + ScrollExtent;
		/* scrollView 的可滚动水平范围是所有子视图的宽度总合。 */
		int ScrollRange = computeHorizontalScrollRange();

		/* 如果当前位置 在ScrollExtent 和 ScrollRange 之间,左右两边的View都显示 */
		if (curScrollLoc > ScrollExtent && curScrollLoc < ScrollRange) {
			if (preImage != null)
				preImage.setVisibility(View.VISIBLE);
			if (nextImage != null)
				nextImage.setVisibility(View.VISIBLE);
			return;
		}
		/* 如果滚动到最左边 */
		if (curScrollLoc == ScrollExtent) {
			if (preImage != null)
				preImage.setVisibility(View.INVISIBLE);
			return;
		}
		/* 如果滚动到最右边 */
		if (curScrollLoc >= ScrollRange) {
			if (nextImage != null)
				nextImage.setVisibility(View.INVISIBLE);
			return;
		}

	}

	private void init() {
		mFrameLayout = new FrameLayout(getContext());
		mFrameLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
		addView(mFrameLayout);
		mSparseArray = new SparseArray<View>();
	}

	private void buildItemView() {
		if (mBaseAdapter == null)
			return;
		LinearLayout linearLayout = new LinearLayout(getContext());
		for (int i = 0; i < mBaseAdapter.getCount(); i++) {
			View view = mBaseAdapter.getView(i, mSparseArray.get(i), this);
			view.setOnClickListener(this);
			mSparseArray.put(i, view);
			linearLayout.addView(mSparseArray.get(i));
		}
		LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.FILL_PARENT);
		layoutParams.gravity = Gravity.CENTER_VERTICAL;
		backView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.navigation_item, null);
		backView.setBackgroundResource(R.drawable.bg_view);
		backView.setPadding(0, 5, 0, 5);
		mFrameLayout.addView(backView, layoutParams);
		mFrameLayout.addView(linearLayout);
	}

	public void setAdapter(BaseAdapter baseAdapter) {
		if (baseAdapter == null)
			return;
		mBaseAdapter = baseAdapter;
		mBaseAdapter.registerDataSetObserver(new DataSetObserver() {
			@Override
			public void onChanged() {
				oldPosition = 0;
				buildItemView();
				super.onChanged();
			}
		});
		mBaseAdapter.notifyDataSetChanged();
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == preImage.getId()) {
			fling(-800);
			return;
		}
		if (v.getId() == nextImage.getId()) {
			fling(800);
			return;
		}
		if (onItemClickListener != null) {
			int position = mSparseArray.indexOfValue(v);
			startAnimation(position);
			oldPosition = position;
			onItemClickListener.click(position);
		}
	}

	private void startAnimation(int position) {
		AnimationSet animationSet = new AnimationSet(true);
		animationSet.addAnimation(buildScaleAnimation(oldPosition, position));
		animationSet.addAnimation(buildTranslateAnimation(oldPosition, position));
		animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
		/* 移动后不复原,不返回动画前的状态位置 */
		animationSet.setFillAfter(true);
		animationSet.setDuration(500);
		backView.startAnimation(animationSet);
		invalidate();
	}

	private Animation buildScaleAnimation(int oldPosition, int position) {
		float oldWidth = getItemView(oldPosition).getWidth();
		float newWidth = getItemView(position).getWidth();
		float fromX = oldWidth / backView.getWidth();
		float toX = newWidth / backView.getWidth();
		ScaleAnimation animation = new ScaleAnimation(fromX, toX, 1f, 1f, Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE,
				0.0f);
		return animation;
	}

	private Animation buildTranslateAnimation(int oldPosition, int position) {
		TranslateAnimation animation = new TranslateAnimation(getItemView(oldPosition).getLeft(), getItemView(position)
				.getLeft(), 0, 0);
		return animation;
	}

	private View getItemView(int position) {
		return mSparseArray.get(position);
	}

	public interface OnItemClickListener {
		void click(int position);
	}

	private OnItemClickListener onItemClickListener;

	public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
		this.onItemClickListener = onItemClickListener;
	}

	public void setImageView(ImageView preImage, ImageView nextImage) {
		this.preImage = preImage;
		this.nextImage = nextImage;
		if (preImage != null) {
			preImage.setOnClickListener(this);
		}
		if (nextImage != null) {
			nextImage.setOnClickListener(this);
		}
	}

}


用法:
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.demo.model.Navigation;
import com.example.demo.widget.NavigationHorizontalScrollView;

public class MainActivity extends Activity{
		
	private Context context;
	private List<Navigation> navs = buildNavigation();
	private NavigationHorizontalScrollView mHorizontalScrollView;
	private TextView tv;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		context=this;
		tv=(TextView)findViewById(R.id.tv);
		tv.setText("You clicked "+navs.get(0).getTitle());
		
		mHorizontalScrollView=(NavigationHorizontalScrollView)findViewById(R.id.horizontal_scrollview);
		mHorizontalScrollView.setImageView((ImageView) findViewById(R.id.iv_pre),(ImageView) findViewById(R.id.iv_next));
				
		mHorizontalScrollView.setOnItemClickListener(new NavigationHorizontalScrollView.OnItemClickListener() {
			
			@Override
			public void click(int position) {
				// TODO Auto-generated method stub
				tv.setText("You clicked "+navs.get(position).getTitle());
			}
		});
		
		mHorizontalScrollView.setAdapter(new NavigationAdapter());
		
	}

	private List<Navigation> buildNavigation() {
		List<Navigation> navigations = new ArrayList<Navigation>();
		navigations.add(new Navigation(0, "url", "首页"));
		navigations.add(new Navigation(1, "url", "新闻"));
		navigations.add(new Navigation(2, "url", "科技"));
		navigations.add(new Navigation(3, "url", "设置"));
		navigations.add(new Navigation(4, "url", "朋友"));
		navigations.add(new Navigation(5, "url", "测试长标题"));
		navigations.add(new Navigation(7, "url", "测试"));
		navigations.add(new Navigation(6, "url", "我的宝贝"));
		return navigations;
	}

	
	class NavigationAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return navs.size();
		}

		@Override
		public Object getItem(int position) {
			return navs.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(context).inflate(R.layout.navigation_item, null);
			}
			((TextView) convertView).setText(navs.get(position).getTitle());
			return convertView;
		}

	}
	
}

布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >

    <ImageView
        android:id="@+id/iv_pre"
        android:layout_width="30dip"
        android:layout_height="30dip"
        android:layout_gravity="center_vertical"
        android:src="@drawable/ic_pre" />

    <com.example.demo.widget.NavigationHorizontalScrollView
        android:id="@+id/horizontal_scrollview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:paddingBottom="2dip"
        android:paddingTop="2dip"
        android:scrollbars="none" />

    <ImageView
        android:id="@+id/iv_next"
        android:layout_width="30dip"
        android:layout_height="30dip"
        android:layout_gravity="center_vertical"
        android:src="@drawable/ic_next" />

	</LinearLayout>
    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    	<TextView 
    	    android:id="@+id/tv"
    	    android:layout_width="wrap_content"
        	android:layout_height="wrap_content"
        	android:textColor="@android:color/black"
        	android:textSize="24sp"
        	android:layout_gravity="center"
    	    />
    </FrameLayout>

</LinearLayout>


具体看附件
  • 大小: 35.7 KB
分享到:
评论

相关推荐

    android顶部横向滑动菜单

    在Android应用开发中,顶部横向滑动菜单是一种常见的交互设计,它允许用户通过左右滑动来切换不同的选项或视图,通常被用于展示多个类别或者功能。这种菜单设计可以节省屏幕空间,提升用户体验,尤其在手机和平板...

    网易新闻之横向滑动菜单

    在Android应用开发中,"网易新闻之横向滑动菜单"是一种常见的用户界面设计,它提供了丰富的导航选项,让用户能够方便地浏览和切换不同的新闻类别。这个功能的核心在于实现一个动态的、可无限滚动的标题栏,并且伴随...

    横向滑动导航

    在"顶部横向导航栏的效果"中,ViewPager经常被用作实现这种效果的主要工具。通常,顶部的导航栏会包含一系列的图标或文字,每个代表一个可滑动的页面。当用户点击某个导航项时,ViewPager会自动滑动到相应的页面,...

    ios-CoolSlidingMenu 仿美团、糯米、大众点评顶部可滑动菜单.zip

    `ios-CoolSlidingMenu`项目正是为了实现类似美团、糯米、大众点评那样顶部可滑动的菜单效果而设计的。这个开源库提供了高度自定义的功能,允许开发者在行或列上实现灵活的滑动效果,为用户的导航体验增添新的维度。 ...

    Android应用源码之高仿网易顶部菜单滑动.rar

    在Android应用开发中,设计和实现用户界面是至关重要的,特别是对于新闻类或者电商类应用,顶部菜单滑动效果能够提供良好的用户体验,增强用户的交互性。"Android应用源码之高仿网易顶部菜单滑动"就是一个这样的示例...

    滑动门多种效果,横向,纵向菜单

    横向滑动门效果适用于水平排列的菜单项,当鼠标悬停在某个菜单项上时,与其关联的内容会从旁边滑动出来。这种效果可以通过CSS的`transition`属性和JavaScript的事件监听来实现。例如,可以使用`mouseover`和`mouse...

    recyclerview 横向纵向滑动,滑动置顶,跳转到某一项item

    为了实现横向滑动,我们需要自定义或使用现有的LayoutManager,例如GridLayoutManager或Horizontal LinearLayoutManager。 1. **设置横纵向滑动**: - 对于横向滑动,我们可以使用Horizontal LinearLayoutManager...

    横向单行菜单栏

    这种菜单通常显示在屏幕顶部或底部,包含一系列水平排列的选项,用户可以通过左右滑动来浏览超出视窗的更多选项。在Android开发中,实现这样的效果通常涉及到自定义视图组件和触摸事件处理。 在这个特定的场景中,...

    JS代码之模仿flickr的横向导航菜单效果.zip

    本示例中的"JS代码之模仿flickr的横向导航菜单效果"是一个典型的Web前端开发案例,它旨在通过JavaScript实现与Flickr网站类似的横向导航菜单。这个压缩包包含了实现这种效果所需的代码和可能的使用说明。 首先,...

    ios-Swift导航栏菜单,可滑动菜单,可展开菜单.zip

    在这个案例中,"ios-Swift导航栏菜单,可滑动菜单,可展开菜单.zip" 提供了一个实现导航栏菜单的解决方案,特别适用于那些希望在应用中添加滑动和展开效果的开发者。 这个项目基于"SCNavTabBar"库,这是一个第三方...

    ios-基于UICollectionView的APP顶部菜单栏.zip

    在这个项目中,`UICollectionView`作为`UIScrollView`的子类,实现了顶部菜单栏的滚动功能,用户可以通过左右滑动来选择不同的菜单项。 文件名“UICollectionViewText”可能指的是包含关于如何配置`...

    iOS 仿网易可滑动菜单

    在实现滑动菜单时,`UIScrollView`是核心组件,因为它提供了横向滑动的能力。 1. **设置UIScrollView属性** - `contentSize`: 滚动视图的总大小,决定了内容可以滚动的范围。为了实现滑动菜单,你需要将`content...

    横向和树形tab tab菜单

    横向Tab菜单通常位于页面顶部或侧边,每个Tab代表一个不同的内容区域。用户点击Tab时,对应的内容会在主区域显示,其他Tab则隐藏。这种设计适用于有多个相关但独立的模块的页面,如网站的不同部分或应用的功能区。...

    css横向导航菜单代码

    【CSS横向导航菜单】是一种常见的网页布局方式,用于在页面顶部展示主要的链接或功能选项。这个设计使得用户可以方便地浏览网站的主要部分,提高用户体验。以下是对标题和描述中涉及的知识点的详细说明: 1. **CSS...

    Android应用源码导航菜单横向左右滑动并和下方的控件实现联动.zip

    2. **ViewPager**:在实现横向滑动菜单时,开发者可能会使用ViewPager。ViewPager是一个用于显示多个视图并允许用户通过水平滑动在它们之间切换的组件。通常,ViewPager会与PagerAdapter一起使用,以管理视图的创建...

    Android 高仿网易新闻抽屉效果+横向菜单+页面滑动-IT计算机-毕业设计.zip

    这篇文档将深入解析《Android高仿网易新闻抽屉效果+横向菜单+页面滑动》的毕业设计项目,旨在帮助读者理解和实现类似的功能。这个项目是一个Android应用源码示例,适用于学习Android开发的学生进行毕业设计或论文...

    横向纵向菜单--JQuery实例

    - 对于横向菜单,可能需要实现滑动效果,可以通过`.animate()`方法实现平滑过渡。 - 对于纵向菜单,当点击主菜单项时,用`.slideToggle()`或`.toggle()`方法来控制子菜单的展开和收起。 5. **动画效果**: - ...

    CSS横向下拉菜单.rar

    "CSS横向下拉菜单"是一个常见的交互式菜单设计,尤其适用于网站的顶部导航栏。这种菜单设计利用CSS(层叠样式表)来实现,通常与JavaScript(JS)结合,以增加动态效果和交互性。下面我们将深入探讨如何创建一个CSS...

    Web菜单效果

    1. 滑动菜单:当鼠标悬停在菜单项上时,子菜单滑动出现,增加趣味性。 2. 触摸友好的下拉菜单:在触摸设备上,用户可以通过手势打开和关闭下拉菜单。 3. 动态加载:对于大型菜单,可以按需加载子菜单,减少初次加载...

Global site tag (gtag.js) - Google Analytics