jjzjj

android - 用于控制音量的自定义旋钮 View ?

coder 2023-12-23 原文

我想在旋钮周围显示进度条。遵循本教程后,我创建了这个 旋钮它工作正常。

但是我如何修改上面的旋钮使其看起来像第二张图片

第一个knob的运行代码如下。

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.MeasureSpec;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;

public class RoundKnobButton extends RelativeLayout implements
        OnGestureListener 
{
    public int eventValue=10;

    //doctory starts 
    Paint p1,p2,p3;

    RectF oval;

    int width;
    //doctory ends
    private GestureDetector gestureDetector;

    private float mAngleDown, mAngleUp;
    private ImageView ivRotor;
    private Bitmap bmpRotorOn, bmpRotorOff;
    private boolean mState = false;
    private int m_nWidth = 0, m_nHeight = 0;

    public interface RoundKnobButtonListener 
    {
        public void onStateChange(boolean newstate);

        public void onRotate(int percentage);
    }


    private RoundKnobButtonListener m_listener;

    public void SetListener(RoundKnobButtonListener l) 
    {
        m_listener = l;
    }

    public void SetState(boolean state)
    {
        mState = state;

        ivRotor.setImageBitmap(state ? bmpRotorOn : bmpRotorOff);
    }

    public RoundKnobButton(Context context, int back, int rotoron,
            int rotoroff, final int w, final int h) {
        super(context);

        //doctory starts 

        width = w;

        p1 = new Paint(1);
        p1.setColor(Color.rgb(86, 86, 86));  
        p1.setStyle(android.graphics.Paint.Style.FILL);



         p2 = new Paint(1);
         p2.setColor(Color.rgb(245, 109, 89));
         p2.setStyle(android.graphics.Paint.Style.FILL);

         p3 = new Paint(1);
         p3.setColor(Color.GREEN);
         p3.setStyle(android.graphics.Paint.Style.STROKE);


        oval = new RectF();

        //doctory ends...

        // we won't wait for our size to be calculated, we'll just store out
        // fixed size
        m_nWidth = w;
        m_nHeight = h;

        // create stator
        ImageView ivBack = new ImageView(context);
        ivBack.setImageResource(back);

        RelativeLayout.LayoutParams lp_ivBack = new RelativeLayout.LayoutParams(
                w, h);
        lp_ivBack.addRule(RelativeLayout.CENTER_IN_PARENT);
        addView(ivBack, lp_ivBack);
        // load rotor images
        Bitmap srcon = BitmapFactory.decodeResource(context.getResources(),
                rotoron);
        Bitmap srcoff = BitmapFactory.decodeResource(context.getResources(),
                rotoroff);
        float scaleWidth = ((float) w) / srcon.getWidth();
        float scaleHeight = ((float) h) / srcon.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);

        bmpRotorOn = Bitmap.createBitmap(srcon, 0, 0, srcon.getWidth(),
                srcon.getHeight(), matrix, true);
        bmpRotorOff = Bitmap.createBitmap(srcoff, 0, 0, srcoff.getWidth(),
                srcoff.getHeight(), matrix, true);
        // create rotor
        ivRotor = new ImageView(context);
        ivRotor.setImageBitmap(bmpRotorOn);
        RelativeLayout.LayoutParams lp_ivKnob = new RelativeLayout.LayoutParams(
                w, h);// LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp_ivKnob.addRule(RelativeLayout.CENTER_IN_PARENT);
        addView(ivRotor, lp_ivKnob);
        // set initial state
        SetState(mState);
        // enable gesture detector
        gestureDetector = new GestureDetector(getContext(), this);
    }

    /**
     * math..
     * 
     * @param x
     * @param y
     * @return
     */
    private float cartesianToPolar(float x, float y) {
        return (float) -Math.toDegrees(Math.atan2(x - 0.5f, y - 0.5f));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (gestureDetector.onTouchEvent(event))
            return true;
        else
            return super.onTouchEvent(event);
    }

    public boolean onDown(MotionEvent event) 
    {
        float x = event.getX() / ((float) getWidth());
        float y = event.getY() / ((float) getHeight());
        mAngleDown = cartesianToPolar(1 - x, 1 - y);// 1- to correct our custom
                                                    // axis direction
        return true;
    }

    public boolean onSingleTapUp(MotionEvent e)
    {
        float x = e.getX() / ((float) getWidth());
        float y = e.getY() / ((float) getHeight());
        mAngleUp = cartesianToPolar(1 - x, 1 - y);// 1- to correct our custom
                                                    // axis direction

        // if we click up the same place where we clicked down, it's just a
        // button press
        if (!Float.isNaN(mAngleDown) && !Float.isNaN(mAngleUp)
                && Math.abs(mAngleUp - mAngleDown) < 10) {
            SetState(!mState);
            if (m_listener != null)
                m_listener.onStateChange(mState);
        }
        return true;
    }

    public void setRotorPosAngle(float deg)
    {
        if (deg >= 210 || deg <= 150) 
        {
            if (deg > 180)
                deg = deg - 360;

            Matrix matrix = new Matrix();
            ivRotor.setScaleType(ScaleType.MATRIX);
        //  matrix.postRotate((float) deg, 210 / 2, 210 / 2);// getWidth()/2,
                                                                // getHeight()/2);

            matrix.postRotate((float) deg, m_nWidth/2, m_nHeight/2);//getWidth()/2, getHeight()/2);
            ivRotor.setImageMatrix(matrix);
        }
    }

    public void setRotorPercentage(int percentage)
    {
        int posDegree = percentage * 3 - 150;

        if (posDegree < 0)
            posDegree = 360 + posDegree;

        setRotorPosAngle(posDegree);
    }

    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        float x = e2.getX() / ((float) getWidth());
        float y = e2.getY() / ((float) getHeight());
        float rotDegrees = cartesianToPolar(1 - x, 1 - y);// 1- to correct our
                                                            // custom axis
                                                            // direction

        if (!Float.isNaN(rotDegrees)) {
            // instead of getting 0-> 180, -180 0 , we go for 0 -> 360
            float posDegrees = rotDegrees;
            if (rotDegrees < 0)
                posDegrees = 360 + rotDegrees;

            // deny full rotation, start start and stop point, and get a linear
            // scale
            if (posDegrees > 210 || posDegrees < 150) {
                // rotate our imageview
                setRotorPosAngle(posDegrees);
                // get a linear scale
                float scaleDegrees = rotDegrees + 150; // given the current
                                                        // parameters, we go
                                                        // from 0 to 300
                // get position percent
                int percent = (int) (scaleDegrees / 3);
                if (m_listener != null)
                    m_listener.onRotate(percent);
                return true; // consumed
            } else
                return false;
        } else
            return false; // not consumed
    }

    public void onShowPress(MotionEvent e) {
        // TODO Auto-generated method stub

    }

    public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
            float arg3) {
        return false;
    }

    public void onLongPress(MotionEvent e) {
    }

    /*@Override
    protected void onDraw(Canvas canvas) 
    {
        super.onDraw(canvas);

        int i = width / 4;

        oval.set(i - i / 2, i / 2, i * 3 + i / 2, i * 3 + i / 2);

        canvas.drawOval(oval, p1);

        canvas.drawArc(oval, -90F, (int)Math.round((360D * Double.valueOf(eventValue).doubleValue()) / 100D), true, p2);

        canvas.drawLine(20, 30, 120, 200, p2);


    }*/

    /*@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int desiredWidth  = width;

        int desiredHeight = width;

        int widthMode  = android.view.View.MeasureSpec.getMode(widthMeasureSpec);

        int widthSize = android.view.View.MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = android.view.View.MeasureSpec.getMode(heightMeasureSpec);

        int heightSize = android.view.View.MeasureSpec.getSize(heightMeasureSpec);

        int measuredWidth;

        int measuredHeight;


        if (widthMode == MeasureSpec.EXACTLY)
        {
            measuredWidth = widthSize ;
        }
        else if (widthMode == MeasureSpec.AT_MOST)
        {
            measuredWidth = Math.min(desiredWidth , widthSize);
        } 
        else
        {
            measuredWidth = desiredWidth;
        }


        if (heightMode == MeasureSpec.EXACTLY)
        {
            measuredHeight = heightSize ;
        }
        else if (heightMode == MeasureSpec.AT_MOST)
        {
            measuredHeight = Math.min(desiredHeight, heightSize );
        }
        else
        {
            measuredHeight = desiredHeight;
        }

        setMeasuredDimension(measuredWidth, measuredHeight);
    }
*/
}

我已经创建了onDraw和onMeasure函数函数,并尝试绘制外部进度,或者我该如何修改它。

编辑

是否可以将旋转百分比更改为 20 。我的意思是它显示进度表 0 到 99。是否可以将其转换为 0 到 12。

最佳答案

使用两个 XML 文件。

circular_progress_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="270"
    android:toDegrees="270">
    <shape
        android:innerRadiusRatio="2.5"
        android:shape="ring"
        android:thickness="1dp">
        <gradient
            android:angle="0"
            android:endColor="#22FA05"
            android:startColor="#22FA05"
            android:type="sweep"
            android:useLevel="false" />
    </shape>
</rotate>

background_circle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="ring"
    android:innerRadiusRatio="2.5"
    android:thickness="1dp"
    android:useLevel="false">

    <solid android:color="#000000" />

</shape>

最后

<ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:indeterminate="false"
        android:progressDrawable="@drawable/circular_progress_drawable"
        android:background="@drawable/background_circle"
        style="?android:attr/progressBarStyleHorizontal"
        android:max="100"
        android:progress="25" />

请注意,根据您拥有的图像位置设置宽度和高度

关于android - 用于控制音量的自定义旋钮 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27700637/

有关android - 用于控制音量的自定义旋钮 View ?的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  6. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  7. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  8. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  9. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  10. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

随机推荐