Android自定义可循环的滚动选择器CycleWheelView

最近碰到个项目要使用到滚动选择器,原生的NumberPicker可定制性太差,不大符合UI要求。
网上开源的WheelView是用ScrollView写的,不能循环滚动,而且当数据量很大时要加载的Item太多,性能非常低。
然后,还是自己写一个比较靠谱,用的是ListView实现的。写完自己体验了一下,性能不错,再大的数据也不怕了。
感觉不错,重新封装了一下,提供了一些接口可以直接按照自己的需求定制,调用方法在MainActivity中。
补个图片:

不多说了,直接上代码:

CycleWheelView.java:

/**
 * Copyright (C) 2015
 *
 * CycleWheelView.java
 *
 * Description:
 *
 * Author: Liao Longhui
 *
 * Ver 1.0, 2015-07-15, Liao Longhui, Create file
 */

package com.example.wheelviewdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * 可循环滚动的选择器
 * @author Liao Longhui
 *
 */
public class CycleWheelView extends ListView {

 public static final String TAG = CycleWheelView.class.getSimpleName();
 private static final int COLOR_DIVIDER_DEFALUT = Color.parseColor("#747474");
 private static final int HEIGHT_DIVIDER_DEFAULT = 2;
 private static final int COLOR_SOLID_DEFAULT = Color.parseColor("#3e4043");
 private static final int COLOR_SOLID_SELET_DEFAULT = Color.parseColor("#323335");
 private static final int WHEEL_SIZE_DEFAULT = 3;

 private Handler mHandler;

 private CycleWheelViewAdapter mAdapter;

 /**
  * Labels
  */
 private List<String> mLabels;

 /**
  * Color Of Selected Label
  */
 private int mLabelSelectColor = Color.WHITE;

 /**
  * Color Of Unselected Label
  */
 private int mLabelColor = Color.GRAY;

 /**
  * Gradual Alph
  */
 private float mAlphaGradual = 0.7f;

 /**
  * Color Of Divider
  */
 private int dividerColor = COLOR_DIVIDER_DEFALUT;

 /**
  * Height Of Divider
  */
 private int dividerHeight = HEIGHT_DIVIDER_DEFAULT;

 /**
  * Color of Selected Solid
  */
 private int seletedSolidColor = COLOR_SOLID_SELET_DEFAULT;

 /**
  * Color of Unselected Solid
  */
 private int solidColor = COLOR_SOLID_DEFAULT;

 /**
  * Size Of Wheel , it should be odd number like 3 or greater
  */
 private int mWheelSize = WHEEL_SIZE_DEFAULT;

 /**
  * res Id of Wheel Item Layout
  */
 private int mItemLayoutId;

 /**
  * res Id of Label TextView
  */
 private int mItemLabelTvId;

 /**
  * Height of Wheel Item
  */
 private int mItemHeight;

 private boolean cylceEnable;

 private int mCurrentPositon;

 private WheelItemSelectedListener mItemSelectedListener;

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

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

 public CycleWheelView(Context context) {
  super(context);
 }

 private void init() {
  mHandler = new Handler();
  mItemLayoutId = R.layout.item_cyclewheel;
  mItemLabelTvId = R.id.tv_label_item_wheel;
  mAdapter = new CycleWheelViewAdapter();
  setVerticalScrollBarEnabled(false);
  setScrollingCacheEnabled(false);
  setCacheColorHint(Color.TRANSPARENT);
  setFadingEdgeLength(0);
  setOverScrollMode(OVER_SCROLL_NEVER);
  setDividerHeight(0);
  setAdapter(mAdapter);
  setOnScrollListener(new OnScrollListener() {
   @Override
   public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (scrollState == SCROLL_STATE_IDLE) {
     View itemView = getChildAt(0);
     if (itemView != null) {
      float deltaY = itemView.getY();
      if (deltaY == 0) {
       return;
      }
      if (Math.abs(deltaY) < mItemHeight / 2) {
       smoothScrollBy(getDistance(deltaY), 50);
      } else {
       smoothScrollBy(getDistance(mItemHeight + deltaY), 50);
      }
     }
    }
   }

   @Override
   public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
     int totalItemCount) {
    refreshItems();
   }
  });
 }

 private int getDistance(float scrollDistance) {
  if (Math.abs(scrollDistance) <= 2) {
   return (int) scrollDistance;
  } else if (Math.abs(scrollDistance) < 12) {
   return scrollDistance > 0 ? 2 : -2;
  } else {
   return (int) (scrollDistance / 6);
  }
 }

 private void refreshItems() {
  int offset = mWheelSize / 2;
  int firstPosition = getFirstVisiblePosition();
  int position = 0;
  if (getChildAt(0) == null) {
   return;
  }
  if (Math.abs(getChildAt(0).getY()) <= mItemHeight / 2) {
   position = firstPosition + offset;
  } else {
   position = firstPosition + offset + 1;
  }
  if (position == mCurrentPositon) {
   return;
  }
  mCurrentPositon = position;
  if (mItemSelectedListener != null) {
   mItemSelectedListener.onItemSelected(getSelection(), getSelectLabel());
  }
  resetItems(firstPosition, position, offset);
 }

 private void resetItems(int firstPosition, int position, int offset){
  for (int i = position - offset - 1; i < position + offset + 1; i++) {
   View itemView = getChildAt(i - firstPosition);
   if (itemView == null) {
    continue;
   }
   TextView labelTv = (TextView) itemView.findViewById(mItemLabelTvId);
   if (position == i) {
    labelTv.setTextColor(mLabelSelectColor);
    itemView.setAlpha(1f);
   } else {
    labelTv.setTextColor(mLabelColor);
    int delta = Math.abs(i - position);
    double alpha = Math.pow(mAlphaGradual, delta);
    itemView.setAlpha((float) alpha);
   }
  }
 }

 /**
  * 设置滚轮的刻度列表
  *
  * @param labels
  */
 public void setLabels(List<String> labels) {
  mLabels = labels;
  mAdapter.setData(mLabels);
  mAdapter.notifyDataSetChanged();
  initView();
 }

 /**
  * 设置滚轮滚动监听
  *
  * @param mItemSelectedListener
  */
 public void setOnWheelItemSelectedListener(WheelItemSelectedListener mItemSelectedListener) {
  this.mItemSelectedListener = mItemSelectedListener;
 }

 /**
  * 获取滚轮的刻度列表
  *
  * @return
  */
 public List<String> getLabels() {
  return mLabels;
 }

 /**
  * 设置滚轮是否为循环滚动
  *
  * @param enable true-循环 false-单程
  */

 public void setCycleEnable(boolean enable) {
  if (cylceEnable != enable) {
   cylceEnable = enable;
   mAdapter.notifyDataSetChanged();
   setSelection(getSelection());
  }
 }

 /*
  * 滚动到指定位置
  */
 @Override
 public void setSelection(final int position) {
  mHandler.post(new Runnable() {
   @Override
   public void run() {
    CycleWheelView.super.setSelection(getPosition(position));
   }
  });
 }

 private int getPosition(int positon) {
  if (mLabels == null || mLabels.size() == 0) {
   return 0;
  }
  if (cylceEnable) {
   int d = Integer.MAX_VALUE / 2 / mLabels.size();
   return positon + d * mLabels.size();
  }
  return positon;
 }

 /**
  * 获取当前滚轮位置
  *
  * @return
  */
 public int getSelection() {
  if (mCurrentPositon == 0) {
   mCurrentPositon = mWheelSize / 2;
  }
  return (mCurrentPositon - mWheelSize / 2) % mLabels.size();
 }

 /**
  * 获取当前滚轮位置的刻度
  *
  * @return
  */
 public String getSelectLabel() {
  int position = getSelection();
  position = position < 0 ? 0 : position;
  try {
   return mLabels.get(position);
  } catch (Exception e) {
   return "";
  }
 }

 /**
  * 如果需要自定义滚轮每个Item,调用此方法设置自定义Item布局,自定义布局中需要一个TextView来显示滚轮刻度
  *
  * @param itemResId 布局文件Id
  * @param labelTvId 刻度TextView的资源Id
  */
 public void setWheelItemLayout(int itemResId, int labelTvId) {
  mItemLayoutId = itemResId;
  mItemLabelTvId = labelTvId;
  mAdapter = new CycleWheelViewAdapter();
  mAdapter.setData(mLabels);
  setAdapter(mAdapter);
  initView();
 }

 /**
  * 设置未选中刻度文字颜色
  *
  * @param labelColor
  */
 public void setLabelColor(int labelColor) {
  this.mLabelColor = labelColor;
  resetItems(getFirstVisiblePosition(), mCurrentPositon, mWheelSize/2);
 }

 /**
  * 设置选中刻度文字颜色
  *
  * @param labelSelectColor
  */
 public void setLabelSelectColor(int labelSelectColor) {
  this.mLabelSelectColor = labelSelectColor;
  resetItems(getFirstVisiblePosition(), mCurrentPositon, mWheelSize/2);
 }

 /**
  * 设置滚轮刻度透明渐变值
  *
  * @param alphaGradual
  */
 public void setAlphaGradual(float alphaGradual) {
  this.mAlphaGradual = alphaGradual;
  resetItems(getFirstVisiblePosition(), mCurrentPositon, mWheelSize/2);
 }

 /**
  * 设置滚轮可显示的刻度数量,必须为奇数,且大于等于3
  *
  * @param wheelSize
  * @throws CycleWheelViewException 滚轮数量错误
  */
 public void setWheelSize(int wheelSize) throws CycleWheelViewException {
  if (wheelSize < 3 || wheelSize % 2 != 1) {
   throw new CycleWheelViewException("Wheel Size Error , Must Be 3,5,7,9...");
  } else {
   mWheelSize = wheelSize;
   initView();
  }
 }

 /**
  * 设置块的颜色
  * @param unselectedSolidColor 未选中的块的颜色
  * @param selectedSolidColor 选中的块的颜色
  */
 public void setSolid(int unselectedSolidColor, int selectedSolidColor){
  this.solidColor = unselectedSolidColor;
  this.seletedSolidColor = selectedSolidColor;
  initView();
 }

 /**
  * 设置分割线样式
  * @param dividerColor 分割线颜色
  * @param dividerHeight 分割线高度(px)
  */
 public void setDivider(int dividerColor, int dividerHeight){
  this.dividerColor = dividerColor;
  this.dividerHeight = dividerHeight;
 }

 @SuppressWarnings("deprecation")
 private void initView() {
  mItemHeight = measureHeight();
  ViewGroup.LayoutParams lp = getLayoutParams();
  lp.height = mItemHeight * mWheelSize;
  mAdapter.setData(mLabels);
  mAdapter.notifyDataSetChanged();
  Drawable backgroud = new Drawable() {
   @Override
   public void draw(Canvas canvas) {
    int viewWidth = getWidth();
    Paint dividerPaint = new Paint();
    dividerPaint.setColor(dividerColor);
    dividerPaint.setStrokeWidth(dividerHeight);
    Paint seletedSolidPaint = new Paint();
    seletedSolidPaint.setColor(seletedSolidColor);
    Paint solidPaint = new Paint();
    solidPaint.setColor(solidColor);
    canvas.drawRect(0, 0, viewWidth, mItemHeight * (mWheelSize / 2), solidPaint);
    canvas.drawRect(0, mItemHeight * (mWheelSize / 2 + 1), viewWidth, mItemHeight
      * (mWheelSize), solidPaint);
    canvas.drawRect(0, mItemHeight * (mWheelSize / 2), viewWidth, mItemHeight
      * (mWheelSize / 2 + 1), seletedSolidPaint);
    canvas.drawLine(0, mItemHeight * (mWheelSize / 2), viewWidth, mItemHeight
      * (mWheelSize / 2), dividerPaint);
    canvas.drawLine(0, mItemHeight * (mWheelSize / 2 + 1), viewWidth, mItemHeight
      * (mWheelSize / 2 + 1), dividerPaint);
   }

   @Override
   public void setAlpha(int alpha) {
   }

   @Override
   public void setColorFilter(ColorFilter cf) {
   }

   @Override
   public int getOpacity() {
    return 0;
   }
  };
  setBackgroundDrawable(backgroud);
 }

 private int measureHeight() {
  View itemView = LayoutInflater.from(getContext()).inflate(mItemLayoutId, null);
  itemView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.WRAP_CONTENT));
  int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
  int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
  itemView.measure(w, h);
  int height = itemView.getMeasuredHeight();
  // int width = view.getMeasuredWidth();
  return height;
 }

 public interface WheelItemSelectedListener {
  public void onItemSelected(int position, String label);
 }

 public class CycleWheelViewException extends Exception {
  private static final long serialVersionUID = 1L;

  public CycleWheelViewException(String detailMessage) {
   super(detailMessage);
  }
 }

 public class CycleWheelViewAdapter extends BaseAdapter {

  private List<String> mData = new ArrayList<String>();

  public void setData(List<String> mWheelLabels) {
   mData.clear();
   mData.addAll(mWheelLabels);
  }

  @Override
  public int getCount() {
   if (cylceEnable) {
    return Integer.MAX_VALUE;
   }
   return mData.size() + mWheelSize - 1;
  }

  @Override
  public Object getItem(int position) {
   return "";
  }

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

  @Override
  public boolean isEnabled(int position) {
   return false;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
   if (convertView == null) {
    convertView = LayoutInflater.from(getContext()).inflate(mItemLayoutId, null);
   }
   TextView textView = (TextView) convertView.findViewById(mItemLabelTvId);
   if (position < mWheelSize / 2
     || (!cylceEnable && position >= mData.size() + mWheelSize / 2)) {
    textView.setText("");
    convertView.setVisibility(View.INVISIBLE);
   } else {
    textView.setText(mData.get((position - mWheelSize / 2) % mData.size()));
    convertView.setVisibility(View.VISIBLE);
   }
   return convertView;
  }
 }
}

MainActivity.java: 

public class MainActivity extends Activity {
 private CycleWheelView cycleWheelView0,cycleWheelView1, cycleWheelView2;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  cycleWheelView0 = (CycleWheelView) findViewById(R.id.cycleWheelView);
  List<String> labels = new ArrayList<>();
  for (int i = 0; i < 12; i++) {
   labels.add("" + i);
  }
  cycleWheelView0.setLabels(labels);
  cycleWheelView0.setAlphaGradual(0.5f);
  cycleWheelView0.setOnWheelItemSelectedListener(new WheelItemSelectedListener() {
   @Override
   public void onItemSelected(int position, String label) {
    Log.d("test", label);
   }
  });

  cycleWheelView1 = (CycleWheelView) findViewById(R.id.cycleWheelView1);
  List<String> labels1 = new ArrayList<>();
  for (int i = 0; i < 24; i++) {
   labels1.add("" + i);
  }
  cycleWheelView1.setLabels(labels1);
  try {
   cycleWheelView1.setWheelSize(5);
  } catch (CycleWheelViewException e) {
   e.printStackTrace();
  }
  cycleWheelView1.setSelection(2);
  cycleWheelView1.setWheelItemLayout(R.layout.item_cyclewheel_custom, R.id.tv_label_item_wheel_custom);
  cycleWheelView1.setOnWheelItemSelectedListener(new WheelItemSelectedListener() {
   @Override
   public void onItemSelected(int position, String label) {
    Log.d("test", label);
   }
  });

  cycleWheelView2 = (CycleWheelView) findViewById(R.id.cycleWheelView2);
  List<String> labels2 = new ArrayList<>();
  for (int i = 0; i < 60; i++) {
   labels2.add("" + i);
  }
  cycleWheelView2.setLabels(labels2);
  try {
   cycleWheelView2.setWheelSize(7);
  } catch (CycleWheelViewException e) {
   e.printStackTrace();
  }
  cycleWheelView2.setCycleEnable(true);
  cycleWheelView2.setSelection(30);
  cycleWheelView2.setAlphaGradual(0.6f);
  cycleWheelView2.setDivider(Color.parseColor("#abcdef"), 2);
  cycleWheelView2.setSolid(Color.WHITE,Color.WHITE);
  cycleWheelView2.setLabelColor(Color.BLUE);
  cycleWheelView2.setLabelSelectColor(Color.RED);
  cycleWheelView2.setOnWheelItemSelectedListener(new WheelItemSelectedListener() {
   @Override
   public void onItemSelected(int position, String label) {
    Log.d("test", label);
   }
  });

 }
}

Item_cyclewheel.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:padding="16dp"
 android:background="@android:color/transparent" >

 <TextView
  android:id="@+id/tv_label_item_wheel"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textSize="20sp"
  android:singleLine="true"
  android:layout_centerHorizontal="true"
  android:layout_centerVertical="true" />

</RelativeLayout>

Item_cyclewheel_custom.xml: 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:padding="16dp"
 android:background="@android:color/transparent" >

 <TextView
  android:id="@+id/tv_label_item_wheel_custom"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:singleLine="true"
  android:layout_alignParentLeft="true"
  android:layout_centerVertical="true" />

 <ImageView
  android:layout_width="25dp"
  android:layout_height="25dp"
  android:layout_centerVertical="true"
  android:layout_alignParentRight="true"
  android:src="@drawable/ic_launcher" />

</RelativeLayout>

activity_main.xml:

<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="horizontal" >

 <com.example.wheelviewdemo.CycleWheelView
  android:id="@+id/cycleWheelView"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_weight="1" >
 </com.example.wheelviewdemo.CycleWheelView>

 <com.example.wheelviewdemo.CycleWheelView
  android:id="@+id/cycleWheelView1"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_weight="1" >
 </com.example.wheelviewdemo.CycleWheelView>

 <com.example.wheelviewdemo.CycleWheelView
  android:id="@+id/cycleWheelView2"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_weight="1" >
 </com.example.wheelviewdemo.CycleWheelView>

</LinearLayout>

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

(0)

相关推荐

  • Android PickerView滚动选择器的使用方法

    手机里设置闹钟需要选择时间,那个选择时间的控件就是滚动选择器,前几天用手机刷了MIUI,发现自带的那个时间选择器效果挺好看的,于是就自己仿写了一个,权当练手.先来看效果: 效果还行吧?实现思路就是自定义一个PickerView,单独滚动的是一个PickerView,显然上图中有分和秒的选择所以在布局里用了两个PickerView.由于这里不涉及到text的点击事件,所以只需要继承View就行了,直接把text用canvas画上去.PickerView的实现的主要难点: 难点1: 字体随距离的渐变

  • Android selector背景选择器的使用详解

    在开发应用中,很多情况下要设计listview或button控件的背景,下面总结一下android的selector的用法:1.在drawable中配置Android的selector.将如下的XML文件保存成你自己命名的.xml文件(比如item_bg.xml),并将该文件放置在drawable文件中,在系统使用时根据ListView中的列表项的状态来使用相应的背景图片. 复制代码 代码如下: <?xml version="1.0" encoding="utf-8&q

  • Android编程中selector背景选择器用法实例分析

    本文实例讲述了Android编程中selector背景选择器用法.分享给大家供大家参考,具体如下: 在Android开发过程中,经常对某一View的背景在不同的状态下,设置不同的背景,增强用户体验.如果按钮,在按下时,背景变化,如果在代码中动态设置,相对比较麻烦.Android为我们提供了selector背景选择器可以非常方便的解决这一问题. Selector的结构描述: 1.android:state_pressed="true/false" true:表示按下状态下使用,false

  • Android自定义View实现角度选择器

    首先来看一下Google Photos的效果 实现最终的效果: 实现思路 仔细观察这个效果,先分析构成结构,我把它分成三部分: 1.表示刻度的点 2.相应点上方的数字 3.控件中央的当前刻度与三角 可以看出,构成元素十分简单,不涉及图片,Drawable,那么只需要用Canvas画出来就好了. 接下来观察手势的操作,查看随着手指滑动,控件做出的变化,这里的变化有: 1.手指按上去时,部分区域变亮(部分区域即为可见区域) 2.随着手指滑动,相应的数字发生移动,当前角度值也发生改变 3.离中心越近,

  • Android View背景选择器编写技巧

    在项目中选择器的使用是非常多的,以下是本人在项目中的一些常用的背景选择器的写法 带边框下划线背景选择器效果图: 上面布局中放了10个CheckBox,然后设置了CheckBox的背景图片位,背景选择器,同时设置了字体的颜色选择器. 带边框下划线背景选择器代码: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com

  • 基于android背景选择器selector的用法汇总

    一.创建xml文件,位置:drawable/xxx.xml,同目录下记得要放相关图片 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <!-- 没有焦点时的背景图片 -->    <item android:dr

  • Android自定义可循环的滚动选择器CycleWheelView

    最近碰到个项目要使用到滚动选择器,原生的NumberPicker可定制性太差,不大符合UI要求. 网上开源的WheelView是用ScrollView写的,不能循环滚动,而且当数据量很大时要加载的Item太多,性能非常低. 然后,还是自己写一个比较靠谱,用的是ListView实现的.写完自己体验了一下,性能不错,再大的数据也不怕了. 感觉不错,重新封装了一下,提供了一些接口可以直接按照自己的需求定制,调用方法在MainActivity中. 补个图片: 不多说了,直接上代码: CycleWheel

  • Android自定义半圆形圆盘滚动选择器

    前段时间公司项目要求做一个特效的滑动选择器,效果如下图的样子: 功能要求:两边的半圆形转盘可以转动,转盘上的图标也一起滚动,蓝红色图标指着的小图标变成高亮选中状态. 第一眼看到这个需求就想到这个必须要用自定义控件来做才行,于是产生了这样的思路: 半圆形的滚动的转盘自定义view继承viewgroup,重写滑动事件,自定义圆盘上图片的摆放角度,至于蓝色和红色箭头图标指向的选中状态可以用坐标数组绘制一个区域来判断是否有符合条件的图标滚动到了这个位置,如果有的话就将这个图标所在的控件透明度设置为1,如

  • Android自定义view实现滚动选择控件详解

    目录 前言 需求 编写代码 主要问题 前言 上篇文章通过一个有header和footer的滚动控件(Viewgroup)学了下MeasureSpec.onMeasure以及onLayout,接下来就用一个滚动选择的控件(View)来学一下onDraw的使用,并且了解下在XML自定义控件参数. 需求 这里就是一个滚动选择文字的控件,还是挺常见的,之前用别人的,现在选择手撕一个,核心思想如下: 1.有三层不同大小及透明度的选项,选中项放在中间 2.接受一个列表的数据,静态时显示三个值,滚动时显示四个

  • Android自定义wheelview实现滚动日期选择器

    本文实例为大家分享了Android实现滚动日期选择器的具体代码,供大家参考,具体内容如下 wheelview滚动效果的View 这段时间需要用到一个时间选择器,但是不能使用日期对话框, 因为它是筛选条件框架下的,只能是View!这个WheelView改造后可以达到要求! 这个wheelview框架使用的类不多,就几个,还有一些资源文件. 我根据这个框架设计了日期的选择器. 主页面: 第一种日期选择器页面: 动态效果: 使用: 具体的实现是一个LoopView的类,这是一个继承View的类! 理解

  • Android自定义ViewFlipper实现滚动效果

    本文实例为大家分享了自定义view实现了类似百度手机助手,首页评论滚动效果. 看效果: gif做的不好,其效果就是:几个viewitem不停的向上滚动,新加入item有个淡入的效果. 说下实现思路:自定义view继承至LinearLayout,控制item数量及其动画效果,实现item复用,传入数据即可,使用方便. 代码: /** * Jiantao.Yang * * @description 仿百度手机助手,评论滚动效果 * @time 2015/1/16 17:37 */ public cl

  • Android自定义滚动选择器实例代码

    Android自定义滚动选择器 实现图片的效果 代码如下 package com.linzihui.widget; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graph

  • Android仿iphone自定义滚动选择器

    本文实例为大家分享了Android仿iphone自定义滚动选择器的具体代码,供大家参考,具体内容如下 一.多的不说,效果图,先走起 二.实例源码 (1)自定义控件 package com.pickerscrollview.views; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import android.annotation.Sup

  • Android自定义View仿IOS圆盘时间选择器

    通过自定义view实现仿iOS实现滑动两端的点选择时间的效果 效果图 自定义的view代码 public class Ring_Slide2 extends View { private static final double RADIAN = 180 / Math.PI; private int max_progress; // 设置最大进度 private int cur_progress; //设置锚点1当前进度 private int cur_progress2; //设置锚点2进度 p

随机推荐