Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIPickerView in Android #132

Open
soapgu opened this issue Apr 9, 2022 · 0 comments
Open

UIPickerView in Android #132

soapgu opened this issue Apr 9, 2022 · 0 comments
Labels
mvvm This issue or pull request already exists problem problem or trouble 安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Apr 9, 2022

  • 前言

在我以前的Swif学习过程中,大致了解UIPickerView控件。

图片
类似这种效果,但是在安卓是没有类似效果,看上去谷歌官方也不想做“同款”了

  • 控件选型

官方没有只有自己造了。那第三方只能从下面因素逐一考虑

  • 官方推荐或者“收编”
  • 使用人群够大
  • 自己可改可控

第一第二条都没有满足的!
图片
推而求其次次,只能github上找一个还入一点眼的

最后选了WheelView
应该感觉简洁,api使用方便
在线库已经失效了,只能引用本地库了

  • 控件使用

首先从github上把项目fork下来,随时准备改
按readme的方式运行效果还过得去。

但是最终控件还需要进入我们的MVVM架构

package com.soap.testpickerview;

import android.view.View;

import androidx.databinding.BindingAdapter;

import com.soap.testpickerview.models.BuildingModel;
import com.wx.wheelview.adapter.ArrayWheelAdapter;
import com.wx.wheelview.widget.WheelView;

import java.util.List;

public class WheelViewBindingAdapters {

    @BindingAdapter(value = {"itemsSource","style","onItemSelected","selectedIndex"},requireAll = false)
    public static <T> void setWheelViewItems(WheelView<T> wheelView , List<T> itemsSource,WheelView.WheelViewStyle style , WheelSelectListener onItemSelected , int selectedIndex){
        if( wheelView.getAdapter() == null ) {
            wheelView.setWheelAdapter(new ArrayWheelAdapter<>(wheelView.getContext()));
            wheelView.setSkin(WheelView.Skin.None);
            wheelView.setWheelSize(5);
            if (style != null) {
                wheelView.setStyle(style);
            }
        }
        if( wheelView.getWheelData() != itemsSource ) {
            wheelView.setWheelData(itemsSource);
        }
        if( onItemSelected != null ) {
            wheelView.setOnWheelItemSelectedListener((i, s) -> onItemSelected.onSelect(i));
        }
        if( wheelView.getCurrentPosition() != selectedIndex ) {
            wheelView.setSelection(selectedIndex);
        }
    }
}

总体和Spinner也差不多

结果使用绑定一开始就崩了!

我的绑定库,一开始就拿不到自定义控件,直接null reference了。

StackOverflow没有高赞回答,从回答的方向来看

  1. 自定义控件本身
  2. 自定义控件构造没弄好

首先网上说了的是自定义控件的构造没重载好。
我加了第四个
public WheelView(Context context, AttributeSet attrs, int defStyleAttr , int defStyleRes)
还是一样

最后怀疑是构造里面做了点不该做的事情
我把init()的函数从构造里面“除名”了

奇迹出现了,控件能绑定了

问题init和样式有关,除名了,显示就不正常了。
一开始我在应用层手工“init”,效果是ok了。问题每一个控件都要自己init也太麻烦了

 @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        this.init();
    }

把init暂时先塞到事件里面,暂时也相安无事

  • 用法

  1. 编译aar文件

Android Studio 的模块默认打包成aar文件,
输出位置为 WheelView\wheelview\build\outputs\aar\wheelview-release.aar
我这里用的release版本

  1. 添加文件引用
    在app的build.grade 里面增加
    implementation files("../lib/wheelview-release.aar")
    当然多模块下这么玩就不对了
    图片

在app模块不直接使用的情况下,build.grade写成
runtimeOnly files("../../../libs/wheelview-release.aar")

使用控件但不是app模块,build.grade写成
compileOnly files("../../../libs/wheelview-release.aar")

大家再意会一下,灵活使用!

  1. xml定义
<com.wx.wheelview.widget.WheelView
            android:id="@+id/wheelview"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:itemsSource="@{dataContext.buildings}"
            app:selectedIndex="@{dataContext.selectBuildingIndex}"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toStartOf="@id/wheel_floor"
            app:onItemSelected="@{(t)->dataContext.onSelectedBuilding(t)}"
            app:style="@{dataContext.style}" />
  1. ViewModel
public class MainViewModel extends ViewModel implements Observable{
    private final List<BuildingModel> buildings = Arrays.asList( new BuildingModel("1","25号楼"),
            new BuildingModel("2","20号楼") );
    private int selectBuildingIndex;

    public MainViewModel(){
        this.style = new WheelView.WheelViewStyle();
        style.textColor = Color.parseColor("#7C7C7D");
        style.selectedTextColor = Color.parseColor("#222222");
        style.textSize = 14;
    }

    public void onSelectedBuilding( int index ){
        if( selectBuildingIndex != index ){
            selectBuildingIndex = index;
            selectFloorIndex = 0;
            selectSpaceIndex = 0;
            this.notifyPropertyChanged(BR.selectFloorIndex);
            this.notifyPropertyChanged(BR.selectSpaceIndex);
            loadFloors();
            loadSpace();
        }
    }

    public List<BuildingModel> getBuildings() {
        return buildings;
    }

    @Bindable
    public int getSelectBuildingIndex() {
        return selectBuildingIndex;
    }

} 

利用前面的的WheelViewBindingAdapters 做好桥梁

暂时项目上只用到模块级别,还没进通用库

@soapgu soapgu added mvvm This issue or pull request already exists 安卓 安卓 problem problem or trouble labels Apr 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mvvm This issue or pull request already exists problem problem or trouble 安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant