3DWheelPicker

3D effect data selection control, source address: github.com/yijiebuyi/3… There are several open source libraries with similar effects, and company projects use a similar timing feature, but it’s not quite as slick as the product requires. So their implementation, download Demo can experience.

Download the Demo

APK Download Link 1: D.firim. pro/ 3DWheelpick…

rendering

function

  • Time to choose
  • Data selection for singular groups
  • Data selection for most groups (support multi-level linking)
  • City selection (city data may be incomplete)
  • Styles can be set dynamically

use

  • Add the following code to project build.gradle
allprojects {
    repositories{... maven { url"https://jitpack.io"}}}Copy the code
  • reference

dependencies {
  implementation 'com. Making. Yijiebuyi: 3 dwheelpicker: v1.1.1'
}

Copy the code

Basic usage:

Use DataPicker (see demo)

Get a single row of data for specific use

  • Use the sample
PickOption option = new PickOption.Builder()
                .setVisibleItemCount(9) // set the number of visible items in the pickerView, which must be singular (1,3,5,7....)
                .setItemSpace(context.getResources().getDimensionPixelOffset(R.dimen.px20)) // Set the spacing between items
                .setItemTextColor(context.getResources().getColor(R.color.font_black)) // Sets the text color of item
                .setItemTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_36px)) // Set the font size for item
                .setVerPadding(context.getResources().getDimensionPixelSize(R.dimen.px20)) // Set the top and bottom padding of the item
                .setShadowGravity(AbstractViewWheelPicker.SHADOW_RIGHT) // Set the scroll bias
                .setShadowFactor(0.5 f) // Set the bias factor of the roller
                .setFingerMoveFactor(0.8 f) // Set the damping factor for finger sliding
                .setFlingAnimFactor(0.7 f) // Set the damping factor for scrolling animation after fast finger release
                .setOverScrollOffset(context.getResources().getDimensionPixelSize(R.dimen.px36)) // Set the maximum offset for scrolling back to the bottom of the scroll wheel
                .setBackgroundColor(Color.WHITE) // Set the background color of the scroll wheel
                .setLeftTitleColor(0xFF1233DD) // Set the color of the text to the left of the bottom popup
                .setRightTitleColor(0xFF1233DD) // Set the color of the text to the right of the bottom popup
                .setMiddleTitleColor(0xFF333333) // Set the color of the text in the middle of the bottom popup
                .setTitleBackground(0XFFDDDDDD) // Set the background color of the title bar of the bottom popbox
                .setLeftTitleText("Cancel") // Set the text to the left of the bottom popup
                .setRightTitleText("Sure") // Set the text to the right of the bottom popup
                .setMiddleTitleText("Please select data") // Set the middle of the bottom pop-up box
                .setTitleHeight(context.getResources().getDimensionPixelOffset(R.dimen.px80)) // Set the title height of the bottom pop-up box
                .build();
 DataPicker.pickData(MainActivity.this, mInitData, getStudents(1), option, new OnDataPickListener<Student>() {
     @Override
     public void onDataPicked(int index, String val, Student data) {
         mInitData = data;
         Toast.makeText(MainActivity.this, val, Toast.LENGTH_SHORT).show(); }});Copy the code
  • You can also use the default Builder and set the properties of interest yourself
    PickOption option = PickOption.getPickDefaultOptionBuilder(mContext)
    .setShadowFactor(0.5 f) // Set the bias factor of the roller
    .setFingerMoveFactor(0.8 f) // Set the damping factor for finger sliding
    .setFlingAnimFactor(0.7 f) // Set the damping factor for scrolling animation after fast finger release
    .build();
Copy the code
  • Time to choose
  /** * get time **@param context
     * @param initDate
     * @param listener
     */
    public static void pickDate(Context context, @Nullable Date initDate, @Nullable PickOption option, final OnDatePickListener listener)
                         
Copy the code
  • Data selection:

To ensure that the data displayed by the Picker control is the desired String, either implement a PickString for the classes in the array (except the String array) or override toString

   /** * when PickString is not implemented, the picker control displays the contents of toString()
   class Student implements PickString {
      public String name;
      public int age;

      public Student(String n, int a) {
          name = n;
          age = a;
      }

      @NonNull
      @Override
      public String toString(a) {
          return age + "Age";
      }

      @Override
      public String pickDisplayName(a) {
          returnname; }}/** * get single row data *@param context
   * @param initData
   * @param srcData
   * @param listener
   * @param <T>
   */
  public static <T> void pickData(Context context, @Nullable T initData, @NonNull final List<T> srcData, 
                                  @Nullable PickOption option, final OnDataPickListener listener
  
 /** * Multi-row data selection (non-cascading data) */
  public static <T> void pickData(Context context, @Nullable List<Integer> initIndex, @NonNullList<List<? >> srcData,@Nullable PickOption option, final OnMultiDataPickListener listener)
                                  
 /** * Multiple row data selection (cascading data) * @param context * @param initIndex * @param srcData * @param listener * @param 
       
         */
       
  public static <T> void pickData(Context context, @Nullable List<Integer> initIndex, @NonNullList<List<? >> srcData,@Nullable PickOption option, boolean wrapper,
                                  final OnMultiDataPickListener listener, final OnCascadeWheelListener cascadeListener)

Copy the code

Set the scroll wheel style (see how to use it in DataPicker)

The styles of the PickerView are described in the Properties of PickOption, including the top title style of the popup, the Wheel style of the PickerView, and the Item style

    /** * set the scroll wheel style *@param pickerView
     * @param option
     */
    private static void setPickViewStyle(IPickerView pickerView, PickOption option) {
        // Set the view style
        pickerView.asView().setBackgroundColor(option.getBackgroundColor());
        pickerView.asView().setPadding(0, option.getVerPadding(), 0, option.getVerPadding());

        // Set the Item style
        pickerView.setTextColor(option.getItemTextColor()); // Sets the text color of item
        pickerView.setVisibleItemCount(option.getVisibleItemCount()); // set the number of visible items, which must be odd: 1,3,5,7,9...
        pickerView.setTextSize(option.getItemTextSize());// Set the text font size for item
        pickerView.setItemSpace(option.getItemSpace());// Set the spacing between items
        pickerView.setLineColor(option.getItemLineColor());// Set the color of the dividing line for item
        pickerView.setLineWidth(option.getItemLineWidth());// Set the width of the item line

        // Set the wheel effect
        pickerView.setShadow(option.getShadowGravity(), option.getShadowFactor()); // set wheel bias, bias factor (bias factor value [0,1])
        pickerView.setScrollMoveFactor(option.getFingerMoveFactor()); // set finger movement to item following scroll sensitivity (value (0,1))
        pickerView.setScrollAnimFactor(option.getFlingAnimFactor()); // set the scroll damping factor (value (0,1))
        pickerView.setScrollOverOffset(option.getOverScrollOffset()); // Sets the offset for maximum rebound when the roller slides to the top or bottom
    }
   
Copy the code
/** * Get the bottom popup box *@param context
     * @param pickerView
     * @return* /
    private static BottomSheet buildBottomSheet(Context context, @Nullable PickOption option, IPickerView pickerView) {
        BottomSheet bottomSheet = new BottomSheet(context);
        if(option ! =null) {
            bottomSheet.setLeftBtnText(option.getLeftTitleText());
            bottomSheet.setRightBtnText(option.getRightTitleText());
            bottomSheet.setMiddleText(option.getMiddleTitleText());
            bottomSheet.setLeftBtnTextColor(option.getLeftTitleColor());
            bottomSheet.setRightBtnTextColor(option.getRightTitleColor());
            bottomSheet.setMiddleTextColor(option.getMiddleTitleColor());
            bottomSheet.setTitleBackground(option.getTitleBackground());

            bottomSheet.setTitleHeight(option.getTitleHeight());
        }
        bottomSheet.setContent(pickerView.asView());
        return bottomSheet;
    }
Copy the code

Cascading Data Use Case (City selection)

   
        // City select (cascade operation) Set OnCascadeWheelListener to cascade
        findViewById(R.id.city_picker).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) { pickCity(AdministrativeUtil.PROVINCE_CITY_AREA, mCascadeInitIndex); }});private void pickCity(int mode, final List<Integer> initIndex) {
        if (mAdministrativeMap == null) {
            mAdministrativeMap = AdministrativeUtil.loadCity(MainActivity.this);
        }

        PickOption option = getPickDefaultOptionBuilder(mContext)
                .setMiddleTitleText("Please select a city")
                .setFlingAnimFactor(0.4 f)
                .setVisibleItemCount(7)
                .setItemTextSize(mContext.getResources().getDimensionPixelSize(com.wheelpicker.R.dimen.font_24px))
                .setItemLineColor(0xFF558800)
                .build();

        DataPicker.pickData(mContext, initIndex,
                AdministrativeUtil.getPickData(mAdministrativeMap, initIndex, mode), option,
                new OnMultiDataPickListener() {
                    @Override
                    public void onDataPicked(List indexArr, List val, List data) {
                        String s = indexArr.toString() + ":" + val.toString();
                        Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show(); initIndex.clear(); initIndex.addAll(indexArr); }},newOnCascadeWheelListener<List<? > > () {@Override
                    publicList<? > onCascade(int wheelIndex, List<Integer> itemIndex) {
                        // Cascade data
                        if (wheelIndex == 0) {
                            return mAdministrativeMap.provinces.get(itemIndex.get(0)).city;
                        } else if (wheelIndex == 1) {
                            return mAdministrativeMap.provinces.get(itemIndex.get(0)).city.get(itemIndex.get(1)).areas;
                        }

                        return null; }}); }Copy the code

Textwheelpicker can also be used

See DateWheelPicker, SingleTextWheelPickerCopy the code

implementation

Inherit View, rewrite onDraw(Canvas Canvas) method to achieve drawing logic

Core class: TextWheelPicker, which can be used to achieve the effect of your wheel. DrawItems (Canvas Canvas) is the core logic for drawing the effect of the wheel. The Camera class of the system and Matrix Matrix change are used to achieve the 3D effect of the wheel.

Draw core code

.float space = computeSpace(rotateDegree, mRadius);
    float relDegree = Math.abs(rotateDegree) / 90;
    canvas.save();
    mCamera.save();
    mRotateMatrix.reset();

    // Rotate matrix transformation
    if (mShadowGravity == SHADOW_RIGHT) {
        mCamera.translate(-mShadowOffset, 0.0);
    } else if (mShadowGravity == SHADOW_LEFT) {
        mCamera.translate(mShadowOffset, 0.0);
    }
    / / rotation
    mWheelPickerImpl.rotateCamera(mCamera, rotateDegree);
    mCamera.getMatrix(mRotateMatrix);
    mCamera.restore();
    mWheelPickerImpl.matrixToCenter(mRotateMatrix, space, mWheelCenterX, mWheelCenterY);
    if (mShadowGravity == SHADOW_RIGHT) {
        mRotateMatrix.postTranslate(mShadowOffset, 0);
    } else if (mShadowGravity == SHADOW_LEFT) {
        mRotateMatrix.postTranslate(-mShadowOffset, 0);
    }
    // Offset matrix transformation
    float depth = computeDepth(rotateDegree, mRelRadius);
    mCamera.save();
    mDepthMatrix.reset();
    mCamera.translate(0.0, depth);
    mCamera.getMatrix(mDepthMatrix);
    mCamera.restore();
    mWheelPickerImpl.matrixToCenter(mDepthMatrix, space, mWheelCenterX, mWheelCenterY);

    mRotateMatrix.postConcat(mDepthMatrix);
    canvas.concat(mRotateMatrix);

    // Draw text.Copy the code

Related classes: ScrollWheelPicker; AbstractWheelPicker

The principle of

reference

Roller calculation schematic: blog.csdn.net/qq_22393017…