栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android仿IOS ViewPager滑动进度条

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap

Android仿IOS ViewPager滑动进度条

最近做项目,碰到如下的需求:ViewPager分页,如果是6页(包括6页)就用圆点,如果是6页以上就用进度条来切换。前面一种交互方法最常见,用小圆点来表示当前选中的页面,这些小圆点称为导航点,很多App都是这种实现方式。当用户第一次安装或升级应用时,都会利用导航页面告诉用户当前版本的主要亮点,一般情况下当行页面有三部分组成,背景图片,导航文字和滑动的原点,即下面的效果:

这里就不作详细的讲解,大家可以参考我以前写过的博客:
ViewPager实现图片轮翻效果
今天来实现ViewPager进度条切换,主要逻辑如下:
MainActivity.java

package com.jackie.slidebarviewdemo.activity; 
 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.TextView; 
 
import com.jackie.slidebarviewdemo.R; 
import com.jackie.slidebarviewdemo.widget.SlideBarView; 
 
public class MainActivity extends AppCompatActivity { 
  private SlideBarView mSlideBarView; 
  private TextView mTextView; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    mSlideBarView = (SlideBarView) findViewById(R.id.slide_bar); 
    mTextView = (TextView) findViewById(R.id.text_view); 
 
    mSlideBarView.setTotalPage(80); 
    mSlideBarView.setonSlideChangeListener(new SlideBarView.onSlideChangeListener() { 
      @Override 
      public void onSlideChange(int page) { 
 mTextView.setText("当前是第" + page + "页"); 
      } 
    }); 
  } 
} 

SlideBarView.java

package com.jackie.slidebarviewdemo.widget; 
 
import android.content.Context; 
import android.util.AttributeSet; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.LinearLayout; 
import android.widget.PopupWindow; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
 
import com.jackie.slidebarviewdemo.R; 
import com.jackie.slidebarviewdemo.utils.ConvertUtils; 
 
 
 
public class SlideBarView extends RelativeLayout { 
  private LayoutInflater mInflater; 
 
  private RelativeLayout mSlideBarView; 
  private View mSlideBarBlock; 
 
  private PopupWindow mPopupWindow; 
  private TextView mPopupText; 
 
  private int mDp40; 
 
  private String mBound = "no"; // no表示没到边界,left为到左边界了,right表示到右边界了 
 
  public interface onSlideChangeListener { 
    void onSlideChange(int page); 
  } 
 
  private onSlideChangeListener mOnSlideChangeListener; 
  public void setonSlideChangeListener(onSlideChangeListener onSlideChangeListener) { 
    this.monSlideChangeListener = onSlideChangeListener; 
  } 
 
  public SlideBarView(Context context) { 
    this(context, null); 
  } 
 
  public SlideBarView(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
  } 
 
  public SlideBarView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
 
    init(context); 
    initEvent(); 
  } 
 
  private void init(Context context) { 
    mInflater = LayoutInflater.from(context); 
    View slideBar = mInflater.inflate(R.layout.slide_bar, null); 
    LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
    addView(slideBar, params); 
 
    mSlideBarView = (RelativeLayout) slideBar.findViewById(R.id.slide_bar_view); 
    mSlideBarBlock = slideBar.findViewById(R.id.slide_bar_block); 
 
    mDp40 = ConvertUtils.dip2px(context, 40); 
  } 
 
  private void initEvent() { 
    mSlideBarView.setonTouchListener(new onTouchListener() { 
      int currentX = 0; 
      int startX = 0; 
 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
 switch (event.getAction()) { 
   case MotionEvent.ACTION_DOWN: 
     currentX = (int) event.getX(); 
     startX = (int) event.getX(); 
 
     // 设置滑块的滑动, 手指第一次点下去把滑块放到手指上 
     int downLeft = currentX - mSlideBarBlock.getMeasuredWidth() / 2; 
     int downTop = mSlideBarBlock.getTop(); 
     int downRight = downLeft + mSlideBarBlock.getWidth(); 
     int downBottom = mSlideBarBlock.getBottom(); 
 
     //边界检测 
     if (downLeft < 0) { 
downLeft = 0; 
downRight = mSlideBarBlock.getMeasuredWidth(); 
     } else if (downRight > mSlideBarView.getMeasuredWidth()) { 
downLeft = mSlideBarView.getMeasuredWidth() - mSlideBarBlock.getMeasuredWidth(); 
downRight = mSlideBarView.getMeasuredWidth(); 
     } 
 
     mSlideBarBlock.layout(downLeft, downTop, downRight, downBottom); 
     break; 
   case MotionEvent.ACTION_MOVE: 
     currentX = (int) event.getX(); 
     int currentPage = currentX * mTotalPage / mSlideBarView.getMeasuredWidth(); 
     if (currentPage < 0) { 
currentPage = 0; 
     } else if (currentPage > mTotalPage) { 
currentPage = mTotalPage; 
     } 
 
     // 设置滑块的滑动 
     int moveLeft = currentX - mSlideBarBlock.getMeasuredWidth() / 2; 
     int moveTop = mSlideBarBlock.getTop(); 
     int moveRight = moveLeft + mSlideBarBlock.getMeasuredWidth(); 
     int moveBottom = mSlideBarBlock.getBottom(); 
 
     //边界处理 
     if (moveLeft < 0) { 
mBound = "left"; 
 
moveLeft = 0; 
moveRight = mSlideBarBlock.getMeasuredWidth(); 
     } else if (moveRight >= mSlideBarView.getMeasuredWidth()) { 
mBound = "right"; 
 
moveLeft = mSlideBarView.getMeasuredWidth() - mSlideBarBlock.getMeasuredWidth(); 
moveRight = mSlideBarView.getMeasuredWidth(); 
     } else { 
mBound = "no"; 
     } 
 
     mSlideBarBlock.layout(moveLeft, moveTop, moveRight, moveBottom); 
     startX = currentX; 
 
     //设置popupWindow的弹出位置 
     if (monSlideChangeListener != null) { 
if (currentPage == mTotalPage) { 
  //防止ViewPager越界 
  currentPage = mTotalPage - 1; 
} 
 
mOnSlideChangeListener.onSlideChange(currentPage); 
 
if (mPopupWindow != null) { 
  mPopupText.setText(currentPage + ""); 
 
  //设置PopupWindow的滑动 
  if (!mPopupWindow.isShowing()) { 
    int[] location = new int[2]; 
    mSlideBarView.getLocationInWindow(location); 
    mPopupWindow.showAsDropDown(mSlideBarView, currentX, location[1] - mDp40); 
  } else { 
    if ("no".equals(mBound)) { 
      int[] location = new int[2] ; 
      mSlideBarView.getLocationInWindow(location); 
      mPopupWindow.update(currentX, location[1] - mDp40, mPopupWindow.getWidth(), mPopupWindow.getHeight(), true); 
    } 
  } 
} 
     } 
     break; 
   case MotionEvent.ACTION_UP: 
     currentX = 0; 
     startX = 0; 
     mPopupWindow.dismiss(); 
     break; 
 } 
 
 return true; 
      } 
    }); 
 
    // 初始化PopupWindow 
    View contentView = mInflater.inflate(R.layout.popup_window, null); 
    mPopupText = (TextView) contentView.findViewById(R.id.popup_text); 
    mPopupWindow = new PopupWindow(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
    mPopupWindow.setContentView(contentView); 
    mPopupWindow.setOutsideTouchable(true); 
    mPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.mipmap.popup_window_bg)); 
    mPopupWindow.setAnimationStyle(0); 
  } 
 
  int mTotalPage = 0; 
  public void setTotalPage(int totalPage) { 
    this.mTotalPage = totalPage; 
  } 
} 

相关的单位转化工具,大家可以拷贝到自己的项目中直接使用。
ConvertUtils.java

package com.jackie.slidebarviewdemo.utils; 
 
import android.content.Context; 
 
public class ConvertUtils { 
  public static int dip2px(Context context, float dpValue) { 
    final float scale = context.getResources().getDisplayMetrics().density; 
    return (int) (dpValue * scale + 0.5f); 
  } 
 
  public static int px2dip(Context context, float pxValue) { 
    final float scale = context.getResources().getDisplayMetrics().density; 
    return (int) (pxValue / scale + 0.5f); 
  } 
   
  public static int px2sp(Context context, float pxValue) { 
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;  
    return (int) (pxValue / fontScale + 0.5f);  
  }  
   
  public static int sp2px(Context context, float spValue) { 
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;  
    return (int) (spValue * fontScale + 0.5f);  
  } 
} 

自定义组合控件,然后实现相关的手势,思路很清晰,代码也很详细,这里就直接贴代码了。
activity_main.xml

 
 
 
   
 
     
 
     
   
 

activity_main.xml

 
 
 
   
 
     
 
     
   
 

popup_window.xml

 
 
   
     
   
 

附上相关的资源文件:
shape_slide_bar_bg.xml

 
 
   
   
 

popup_window_bg.9.png


效果如下:

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160052.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号