Android之自己定义(上方标题随ViewPager手势慢慢滑动)

近期非常蛋疼,项目要模仿网易新闻的样式去做。上次把仿网易新闻client的下拉刷新写出来了。这次是ViewPager的滑动,同一时候ViewPager的上面标题下划线尾随者移动。本来通过ViewPager的OnPagerChangeListener的监听事件就能够完毕,可是做出来之后,由于须要一直的刷新,所以非常卡。一气之下。呵呵。自己全然的画了。整个点击事件,滑动事件都自己处理了。

效果图例如以下:

下标的长宽是随之改变的。

使用方式:

我的布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

>

<com.flyme.columnhorizontalscrollview.ColumnHorizontalScrollView

android:layout_width="match_parent"

android:paddingLeft="20dip"

android:paddingRight="20dip"

android:layout_height="100dip"

android:id="@+id/title"

/>

<android.support.v4.view.ViewPager

android:background="@android:color/holo_orange_light"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:id="@+id/viewpager"

/>

</LinearLayout>

非常easy。把自己定义的布局放在ViewPager的上面,非常任意了。你想放哪就放哪。

在Activity中的使用方式为:

ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);

ColumnHorizontalScrollView title = (ColumnHorizontalScrollView) findViewById(R.id.title);

mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {

@Override

public int getCount() {

return 10;

}

@Override

public Fragment getItem(int arg0) {

return new MyFragment(arg0);

}

});

title.setTitle("上市的公司","历史","游戏啊","房产证","精选的搞笑片段","段子","电脑硬件","热点","轻松一刻","时尚");  //这个是设置标题的

title.setspace(40);

title.setViewPager(mViewPager);  //这个是将ViewPager对象给自己定义的View

我就把自己定义的类代码贴出来吧:比較懒了,时间比較紧。代码封装的不好,也没怎么封装。见谅。

public class ColumnHorizontalScrollView extends View implements OnPageChangeListener {

private Context context;

private int width ;

private int padingLeft;

private int padingRight ;

private float lineStartX = 0  ;

private float lineEndX = 0  ;

private Paint textPaint;

private int textWidth ;

private int lastPosition = 0 ;

private float lineScale = 0 ;

private ViewPager mViewPager ;

/**

* 这些事默认设置的

*/

private static final int DEFULT_TEXT_COLOR = Color.BLACK;

private static final int DEFULT_TEXT_SIZE = 40;

private  static final int DEFULT_LINE_COLOR = Color.RED;

private static final int DEFULT_LINE_STRO = 5;

private String [] str ; // 存储 题要显示的字符

private float [] strX ; // 存储 每一个字符  開始的X位置

private float [] strWidth ;  // 存储每一个字符的长度

private int startX; // 与手势相关    记录按下的X的坐标

private int recordDownX = 0 ;

private OnClickOneListener mOnClickOneListener ;

private OverScroller mScroller;

public ColumnHorizontalScrollView(Context context, AttributeSet attrs,

int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context);

}

public ColumnHorizontalScrollView(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public ColumnHorizontalScrollView(Context context) {

super(context);

init(context);

}

/**

* 初始化的时候须要new出来的一些类,和必要的设置

* @param context

*/

private void init(Context context){

this.context = context ;

mScroller = new OverScroller(context,new LinearInterpolator());

textPaint = new Paint();

linePaint = new Paint();

textPaint.setColor(DEFULT_TEXT_COLOR);

textPaint.setTextSize(DEFULT_TEXT_SIZE);

textPaint.setTypeface(Typeface.SANS_SERIF);

linePaint.setColor(DEFULT_LINE_COLOR);

linePaint.setStrokeWidth(DEFULT_LINE_STRO);

}

/**

* 绘图

*/

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (str == null) {

return ;

}

measureSize();

drawText(canvas); //画字

measureLineSize();//測量下划线的位置

drawLine(canvas);//画下划线

}

/**

* 这个是用来通过Scroller来控制缓冲变化的   后来不须要了

*/

@Override

public void computeScroll() {

if (mScroller.computeScrollOffset()) {

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

}

super.computeScroll();

postInvalidate();

}

/**

* 画字的详细代码

* @param canvas

*/

private  void drawText(Canvas canvas){

int totel = 0 ;

for (int i = 0; i < str.length; i++) {

if (i == 0 ) {

totel += padingLeft;

}

strX[i] = totel ;

canvas.drawText(str[i], strX[i], textHeight, textPaint);

float oneTextWidth = textPaint.measureText(str[i]);

totel =(int) (totel +  oneTextWidth +space);

strWidth[i] = oneTextWidth ;

}

textWidth = totel - space  +padingLeft ;

}

private void drawLine(Canvas canvas){

canvas.drawLine(lineStartX, lineHeight ,lineEndX , lineHeight, linePaint);

}

private void measureSize(){

width = getWidth();

height = getHeight();

padingLeft = getPaddingLeft();

padingRight = getPaddingRight();

textHeight = (int) (height / 2 - (textPaint.descent() + textPaint.ascent())/2);

lineHeight = (int) (textHeight - (textPaint.descent() + textPaint.ascent()));

}

private void measureLineSize(){

lineStartX = strX[lastPosition] - space / 2 + (strWidth[lastPosition] + space )* lineScale;

if ((lastPosition + 1) == mViewPager.getAdapter().getCount()) {

lineEndX = strX[lastPosition] + strWidth[lastPosition] + space / 2 ;

}else {

lineEndX = strX[lastPosition] + strWidth[lastPosition] + space / 2 + ( strWidth[lastPosition + 1] + space ) * lineScale;

}

}

public void setTitle(String ...str){

this.str = str ;

strX = new float[str.length];

strWidth = new float[str.length];

}

private int space = 0 ;

private Paint linePaint;

private int lineHeight;

private int height;

private int textHeight;

public void setspace(int space){

this.space = space ;

}

public void setTextColorResourceId(int colorid){

int color = context.getResources().getColor(colorid);

textPaint.setColor(color);

}

public void setTextColor(int color){

textPaint.setColor(color);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

startX = recordDownX = (int) event.getX();

break;

case MotionEvent.ACTION_MOVE:

int moveX = (int) event.getX();

int scrollX = getScrollX();

if (Math.abs(moveX - recordDownX ) > 32 ) {

smootMove(scrollX , startX - moveX);

}

startX = (int) event.getX();

break;

case MotionEvent.ACTION_UP:

int upX = (int) event.getX();

if (Math.abs(upX - recordDownX ) < 32 ) {

int position = decidePosition(upX);

setPosition(position);

if (mOnClickOneListener != null) {

mOnClickOneListener.onClick(position) ;

}

}

break;

}

return true;

}

private int  decidePosition(int upX){

for (int i = 0; i < strX.length; i++) {

if ((upX + getScrollX()) < (strX[i] + strWidth[i]) + space / 2) {

return i ;

}

}

return 0 ;

}

public void setPosition(int position){

//        lastPosition = position ;

//        int scrollX = getScrollX();

//        int location = (int) (strX[lastPosition] - space - 20);

//        int dy = (int)(location  - getScrollX());

//        if ((location + width) > (textWidth + padingRight ) ) {

//            mScroller.startScroll(scrollX, 0,textWidth + padingRight - width - getScrollX()  , 0, 200);

//        }else {

//            mScroller.startScroll(scrollX, 0, dy , 0, 200);

//        }

//        if ((scrollX + dy ) > (textWidth+padingRight - width)) {

//            mScroller.startScroll(scrollX, 0, textWidth+padingRight - width - scrollX , 0, 200);

//        }else {

//            mScroller.startScroll(scrollX, 0, dy , 0, 200);

//        }

mViewPager.setCurrentItem(position);

}

private void smootMove(int scrollX , int dy){

if ((scrollX <= 0 && dy > 0 && textWidth > width)  || (scrollX > 0)) {

if ((scrollX + dy) < 0 ) {

scrollTo(0 , 0);

}else {

if ((scrollX + dy + getWidth()) > (textWidth+padingRight )) {

scrollTo(textWidth +padingRight - getWidth() , 0);

}else {

scrollTo(scrollX + dy , 0);

}

}

}

}

public void setViewPager(ViewPager mViewPager){

this.mViewPager = mViewPager;

if (this.mViewPager != null) {

this.mViewPager.setOnPageChangeListener(this);

}

}

/**

* dip转为 px

*/

public int dip2px(float dipValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dipValue * scale + 0.5f);

}

@Override

public void onPageScrollStateChanged(int arg0) {

}

@Override

public void onPageScrolled(int lastPosition, float scale, int location) {

this.lastPosition = lastPosition ;

lineScale = scale ;

invalidate();

smootMove((int)(strX[lastPosition] - space - 20 ) ,(int)((strWidth[lastPosition] + space )*  lineScale));

}

@Override

public void onPageSelected(int arg0) {

}

public void setOnClickOneListener (OnClickOneListener mOnClickOneListener){

this.mOnClickOneListener = mOnClickOneListener ;

}

/**

* 内部接口    是点击事件的接口

* @author lenovo

*

*/

interface OnClickOneListener{

public void onClick(int position);

}

}

over。

关于bug:

这个做的还不是非常完好。另一些东西没有做适配。

假设有人用,在使用过程中出现故障,你能够自己做一下简单的适配。

源代码下载地址:

http://pan.baidu.com/s/1sj0lIxR

我的github地址:https://github.com/flyme2012

我的博客园 博客地址:http://www.cnblogs.com/flyme2012/

时间: 2024-11-15 19:26:23

Android之自己定义(上方标题随ViewPager手势慢慢滑动)的相关文章

Android之自定义(上方标题随ViewPager手势慢慢滑动)

最近很蛋疼,项目要模仿网易新闻的样式去做.上次把仿网易新闻客户端的下拉刷新写出来了,这次是ViewPager的滑动,同时ViewPager的上面标题下划线跟随者移动,本来通过ViewPager的OnPagerChangeListener的监听事件就可以完成,但是做出来之后,因为需要一直的刷新,所以很卡,一气之下,呵呵,自己完全的画了.整个点击事件,滑动事件都自己处理了. 效果图如下: 下标的长宽是随之改变的. 使用方式: 我的布局文件: <LinearLayout xmlns:android=&qu

Android典型界面设计(6)——ActionBar Tab+ViewPager+Fagment实现滑动导航

一.问题描述 在Android典型界面设计一文中,实现典型滑动导航界面,其实使用ActionBar 也可以轻松实现这一效果,甚至也可实现类似Android典型界面设计(3)的双导航效果.可见ActionBar还是比较强大的,关键要深入进去.灵活的运用,下面我们就使用ActionBar实现如图所示的效果: 二.本例特点 1.  兼容低版本 2. 使用ActionBar 分体设计(split) 3. Tab使用自定义View 4. 结合ViewPager实现滑动导航 三.代码讲解: 1.在项目中加入

android ViewPager页面左右滑动切换

我们日常生活中用到的微博,QQ,微信等app在进行页面左右滑动的时候,很多都可以用ViewPager来实现.可以说,ViewPager在android开发中十分常见并且特别实用. Viewpager在android.support.v4.view这个软件包中, android.support.v4.view.jar是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.所以低版本开发时必须加入android-support-v4.jar,并且在XML

【Android UI设计与开发】使用ViewPager实现欢迎引导页面

一.实现的效果图 每次看别人的代码前,必需要先看实现的效果图达到了一个什么样的效果,是不是跟自己想要实现的效果类似.有图才有真相嘛,同一时候,最下方有源代码的下载地址,差点儿源代码的每一行都有凝视,写的通俗易懂.很清晰.        二.编码前的准备工作 ViewPager是Android3.0之后提供的新特性,所以要想让你的应用向下兼容就必需要android-support-v4.jar这个包的支持.这是一个来自google提供的一个附加包. 三.项目结构图 四.详细的编码实现 1.  布局

Android自动滚动 轮播循环的ViewPager

主要介绍如何实现ViewPager自动播放,循环滚动的效果及使用.顺便解决ViewPager嵌套(ViewPager inside ViewPager)影响触摸滑动及ViewPager滑动速度设置问题. 项目已开源Android Auto Scroll [email protected],欢迎star和fork. 示例APK可从这些地址下载:Google Play,  360手机助手,  百度手机助手,  小米应用商店,  豌豆荚 示例代码地址见AutoScrollViewPagerDemo,效

Android禁止ViewPager的左右滑动

转载请注明出处:http://blog.csdn.net/allen315410/article/details/40744287 有时候在开发中会遇到一些"诡异"的要求,比如在ViewPager中嵌入ListView,或者再嵌入一个ViewPager,那么在滑动的时候就会造成被嵌入的XXView不能滑动了,那么现在就把最外层的ViewPager禁止滑动吧,让被嵌入的XXView获得滑动事件好了.关于解决方法,网上也有很多说法,基本上是一致的,但是需要理解这个Android下的事件分发

114、Android禁止ViewPager的左右滑动

有时候在开发中会遇到一些“诡异”的要求,比如在ViewPager中嵌入ListView,或者再嵌入一个ViewPager,那么在滑动的时候就会造成被嵌入的XXView不能滑动了,那么现在就把最外层的ViewPager禁止滑动吧,让被嵌入的XXView获得滑动事件好了.关于解决方法,网上也有很多说法,基本上是一致的,但是需要理解这个Android下的事件分发机制才行,不明白事件分发机制的,上网查些资料看看,然后我这里也有简单的介绍,请参看博客Android自定义控件——侧滑菜单的下方. 怎样禁止V

Android实现图片轮显效果——自定义ViewPager控件

一.问题概述 使用ViewPager控件实现可横向翻页.水平切换图片等效果,但ViewPager需要手动滑动才能切换页面,图片轮显效果的效果本质上就是在ViewPager控件的基础上让它能自动的进行切换,所以实现图片轮显步骤如下: 1.  扩展ViewPager自定义一个MyScrollImageView类 2.  为MyScrollImageView定义适配器,装载图片信息 3.  定义图片滑动动画时间控制类 接下来我们就一步步实现下图案例: 二.实现套路 1.为自定义ViewPager控件编

Android ViewPager内容部分随手势上下滑动隐藏与显示Indicator效果的实现

效果 ViewPager中的内容,比如ListView手势上下滑动,当内容向下滑动时,即手势上划,隐藏indictor,当内容向上滑动时,即手势下滑,显示indicator,效果如图所示 编码 借用两个库来快速完成 1. ViewPagerIndicator 2. ObservableScrollView 将两个库引入项目中去,快速的搭建一个ViewPager框架后,在ViewPager每页对应的Fragment的布局中增加一个ListView,这个ListView使用ObservableScr