«

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

时间:2024-3-2 19:46     作者:韩俊     分类: Android


最近很蛋疼,项目要模仿网易新闻的样式去做。上次把仿网易新闻客户端的下拉刷新写出来了,这次是ViewPager的滑动,同时ViewPager的上面标题下划线跟随者移动,本来通过ViewPager的OnPagerChangeListener的监听事件就可以完成,但是做出来之后,因为需要一直的刷新,所以很卡,一气之下,呵呵,自己完全的画了。整个点击事件,滑动事件都自己处理了。

效果图如下:

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

使用方式:

我的布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quot;
xmlns:tools="http://schemas.android.com/tools&quot;
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>

&lt;com.flyme.columnhorizontalscrollview.ColumnHorizontalScrollView 
    android:layout_width=&quot;match_parent&quot;
    android:paddingLeft=&quot;20dip&quot;
    android:paddingRight=&quot;20dip&quot;
    android:layout_height=&quot;100dip&quot;
    android:id=&quot;@&#43;id/title&quot;
    /&gt;

&lt;android.support.v4.view.ViewPager
    android:background=&quot;@android:color/holo_orange_light&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:id=&quot;@&#43;id/viewpager&quot;
    /&gt;

</LinearLayout>

很简单,把自定义的布局放在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(&quot;上市的公司&quot;,&quot;历史&quot;,&quot;游戏啊&quot;,&quot;房产证&quot;,&quot;精选的搞笑片段&quot;,&quot;段子&quot;,&quot;电脑硬件&quot;,&quot;热点&quot;,&quot;轻松一刻&quot;,&quot;时尚&quot;);  //这个是设置标题的  

    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 &lt; str.length; i&#43;&#43;) {
        if (i == 0 ) {
            totel &#43;= padingLeft;
        }
        strX[i] = totel ;
        canvas.drawText(str[i], strX[i], textHeight, textPaint);
        float oneTextWidth = textPaint.measureText(str[i]);
        totel =(int) (totel &#43;  oneTextWidth &#43;space);
        strWidth[i] = oneTextWidth ;
    }
    textWidth = totel - space  &#43;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() &#43; textPaint.ascent())/2); 
    lineHeight = (int) (textHeight - (textPaint.descent() &#43; textPaint.ascent()));
}

private void measureLineSize(){
    lineStartX = strX[lastPosition] - space / 2 &#43; (strWidth[lastPosition] &#43; space )* lineScale;
    if ((lastPosition &#43; 1) == mViewPager.getAdapter().getCount()) {
        lineEndX = strX[lastPosition] &#43; strWidth[lastPosition] &#43; space / 2 ;          
    }else {
        lineEndX = strX[lastPosition] &#43; strWidth[lastPosition] &#43; space / 2 &#43; ( strWidth[lastPosition &#43; 1] &#43; 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 ) &gt; 32 ) {
            smootMove(scrollX , startX - moveX);
        }
        startX = (int) event.getX();
        break;
    case MotionEvent.ACTION_UP:
        int upX = (int) event.getX();
        if (Math.abs(upX - recordDownX ) &lt; 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 &lt; strX.length; i&#43;&#43;) {
        if ((upX &#43; getScrollX()) &lt; (strX[i] &#43; strWidth[i]) &#43; 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 &lt;= 0 &amp;&amp; dy &gt; 0 &amp;&amp; textWidth &gt; width)  || (scrollX &gt; 0)) {
        if ((scrollX &#43; dy) &lt; 0 ) {
            scrollTo(0 , 0);
        }else {
            if ((scrollX &#43; dy &#43; getWidth()) &gt; (textWidth&#43;padingRight )) {
                scrollTo(textWidth &#43;padingRight - getWidth() , 0);
            }else {
                scrollTo(scrollX &#43; 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 &#43; 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] &#43; 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/

        <p>版权声明:本文为博主原创文章,未经博主允许不得转载。</p>

标签: android

热门推荐