Andoird仿IOS滚轮选择控件

最近也是在找工作,比较艰辛,但是也有收获,希望合适的工作就在不远处吧。虽然写博客也没什么人看,但是还是坚持写一写,也算是感情的一种寄托。我比较爱写些自定义控件,因为让别人用我写的东西很有成就感,今天就再分享一个自定义控件,是一个仿IOS的滚轮选择控件,我尽量把代码写好懂一点,这样其他小伙伴要参考或是修改也方便一些。

每天都要过得开心 ( ゜- ゜)つロ乾杯 !


Demo

Demo地址 https://github.com/wdzawdh/WheelDialog

效果图

使用方法

setLabels方法用来设置选项。

WheelDialog wheelDialog = new WheelDialog(this);
wheelDialog.setLabels(list);
wheelDialog.setOnWheelSelectListener(
                 new WheelDialog.OnWheelSelectListener() {
    @Override
    public void onClickOk(int index, String selectLabel) {
        Toast.makeText(getApplicationContext(), selectLabel
        , Toast.LENGTH_SHORT).show();
    }
});
wheelDialog.show();

关键代码

1.控制Dialog宽度充满屏幕并且在屏幕底部
//在Dialog构造中设置window属性
Window window = getWindow();
window.setBackgroundDrawable(new ColorDrawable(Color.argb(0, 0, 0, 0)));
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
//设置dialog宽度充满屏幕
window.getDecorView().setPadding(0, 0, 0, 0);
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);
2.滚轮使用ListView实现

使用ListView实现要克服几个问题。
1.不管怎么滑动,最终item都要两条线之间。
2.要保证所有item都能滚动到两线之间。

问题一:保证不管怎么滑动,最终item都要两条线之间
/**
 * 在onScrollStateChanged中调用,监听滚动事件
 */
private void refreshState(int scrollState) {
    //监听SCROLL_STATE_IDLE滑动停止事件
    if (scrollState == SCROLL_STATE_IDLE) {
        View itemView = getChildAt(0);
        if (itemView == null) {
            return;
        }
        float deltaY = itemView.getY();
        if (deltaY == 0) {
            return;
        }
        //控制item滚动到两线之间
        if (Math.abs(deltaY) < mItemHeight / 2) {
            smoothScrollBy(getDistance(deltaY), 50);
        } else {
            smoothScrollBy(getDistance(mItemHeight + deltaY), 50);
        }
    }
}
/**
 * 用于逐渐滑动到目标位置,参数scrollDistance越小返回值越小,滑动越慢。
 * 直到返回0,那么smoothScrollBy(0)就不会再引起refreshState的循环调用。
 */
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);
    }
}
问题二:保证所有item都能滚动到两线之间

WheelListView.WHEEL_SIZE是滚轮展示的item数,默认是5。
前后添加各添加两个辅助的item来保证所有item都能滚动到两线之间。

class WheelAdapter extends BaseAdapter {

    private List<String> mData = new ArrayList<>();
    ...
    @Override
    public int getCount() {
        //这里多加了4个辅助的item是为了前后的item都能滚动到两线之间。
        return mData.size() + WheelListView.WHEEL_SIZE - 1;
    }

    @Override
    public String getItem(int position) {
        return mData.get(position - WheelListView.WHEEL_SIZE / 2);
    }
    ...
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.widget_wheel_item, null);
        }
        TextView textView = (TextView) convertView
                  .findViewById(R.id.tv_label_item_wheel);

        int start = WheelListView.WHEEL_SIZE / 2;
        int end = mData.size() + WheelListView.WHEEL_SIZE / 2 - 1;
        if (position < start || position > end) {
            //范围外的是辅助的item,不显示
            convertView.setVisibility(View.INVISIBLE);
        } else {
            textView.setText(getItem(position));
            convertView.setVisibility(View.VISIBLE);
        }
        return convertView;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值