首页 > 解决方案 > 如何创建自定义 UI 组件,如响应式搜索栏?

问题描述

我想在 android 中创建自定义滑块或搜索栏(就像在 gif 中,底部和右侧的滑块一样),您能否为我提供如何实现此目的的任何相关过程。自定义滑块

标签: androiduser-interfacegraphics

解决方案


经过几天的搜索,我终于获得了足够的资源来解决问题陈述。对于陈述者,请通过以下资源:

1) https://guides.codepath.com/android/Basic-Painting-with-Views

2) https://guides.codepath.com/android/Progress-Bar-Custom-View

3) https://developer.android.com/guide/topics/ui/custom-components

基本步骤 -

  • 使用您自己的类扩展现有的 View 类或子类。
  • 覆盖超类中的一些方法。要覆盖的超类方法以“on”开头,例如 onDraw()、onMeasure() 和 onKeyDown()。这类似于您为生命周期和其他功能挂钩覆盖的 Activity 或 ListActivity 中的 on... 事件。
  • 使用新的扩展类。完成后,您的新扩展类可以用来代替它所基于的视图。

下面是在画布中演示工作时钟的代码 -

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.Calendar;

    /**
     * Created by moonis
     * on 23/06/18.
     */
    public class CustomClock extends View {
        private int height, width = 0;
        private int padding = 0;
        private int fontSize = 0;
        int numeralSpacing = 0;
        private int handTruncation, hourHandTruncation = 0;
        private int radius = 0;

        private Paint paint;

        private boolean isInit;
        private int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        private Rect rect = new Rect();

        public CustomClock(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            setFocusable(true);
            setFocusableInTouchMode(true);
        }

        private void initClock() {
            height = getHeight();
            width = getWidth();
            padding = numeralSpacing + 50;
            fontSize = (int) DeviceDimensionHelper.convertDpToPixel(13, getContext());
            int min = Math.min(height, width);
            radius = min / 2 - padding;
            handTruncation = min / 20;
            hourHandTruncation = min / 7;

            paint = new Paint();
            isInit = false;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (!isInit) {
                initClock();
            }
            canvas.drawColor(Color.BLACK);
            drawCircle(canvas);
            drawCentre(canvas);
            drawNumeral(canvas);
            drawHands(canvas);
            postInvalidateDelayed(500);
        }


        private void drawCircle(Canvas canvas) {
            paint.reset();
            paint.setColor(Color.WHITE);
            paint.setAntiAlias(true);
            paint.setStrokeWidth(5);
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawCircle(width / 2, height / 2, radius + padding - 10, paint);
        }

        private void drawCentre(Canvas canvas) {
            paint.setStyle(Paint.Style.FILL);
            canvas.drawCircle(width / 2, height / 2, 12, paint);
        }

        private void drawNumeral(Canvas canvas) {
            paint.setTextSize(fontSize);
            for (int number : numbers) {
                String tmp = String.valueOf(number);
                paint.getTextBounds(tmp, 0, tmp.length(), rect);
                double angle = Math.PI / 6 * (number - 3);
                int x = (int) (width / 2 + Math.cos(angle) * radius - rect.width() / 2);
                int y = (int) (height / 2 + Math.sin(angle) * radius - rect.height() / 2);
                canvas.drawText(tmp, x, y, paint);
            }
        }

        private void drawHands(Canvas canvas) {
            Calendar c = Calendar.getInstance();
            float hour = c.get(Calendar.HOUR_OF_DAY);
            hour = hour > 12 ? hour - 12 : hour;
            drawHand(canvas, (hour + c.get(Calendar.MINUTE) / 60) * 5f, true);
            drawHand(canvas, c.get(Calendar.MINUTE), false);
            drawHand(canvas, c.get(Calendar.SECOND), false);
        }

        private void drawHand(Canvas canvas, double loc, boolean isHour) {
            double angle = Math.PI * loc / 30 - Math.PI / 2;
            int handRadius = isHour ? radius - handTruncation - hourHandTruncation : radius - handTruncation;
            canvas.drawLine(width / 2, height / 2, (float) (width / 2 + Math.cos(angle) * handRadius), (float) (height / 2 + Math.sin(angle) * handRadius), paint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float touchX = event.getX();
            float touchY = event.getY();
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    //code to move clock hands on screen gestures
                    break;
                case MotionEvent.ACTION_MOVE:
                   //code to move clock hands on screen gestures
                    break;
                default:
                    return false;
            }
            //redraw view
            postInvalidate();
            return true;
        }
    }

最后,这个库可用于实现所需的输出 -

https://github.com/moldedbits/android-dial-picker


推荐阅读