【问题标题】:android Seekbar show progress value along the seekbarandroid Seekbar沿seekbar显示进度值
【发布时间】:2017-01-21 01:51:07
【问题描述】:

我有一个listviewseekbar,每个seekbar 代表产品价值的100%。通过移动seekbar 可以更改% 值,我想在用户拖动seekbar 时沿搜索栏显示值的变化。我确实希望添加另一个更新值的文本框。

我更多地关注在搜索栏指针顶部显示一个小视图的选项,它出现 onStartTracking 并消失 onStopTracking 事件。

有没有办法做到这一点?

【问题讨论】:

    标签: android android-seekbar


    【解决方案1】:

    这是一种简单的方法,

    • 在您的 XML 中添加 textView
    • 随着seekBar的移动改变它的位置
    • 这将使用setX()定位它
    • 如果您愿意,也可以将 setY() 指定为 Y 位置
    • 如果您想隐藏,请编写一些逻辑并在需要时使 textView Visibility GONE 消失。

    示例:

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                    @Override
                    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    
                        int val = (progress * (seekBar.getWidth() - 2 * seekBar.getThumbOffset())) / seekBar.getMax();
                        textView.setText("" + progress);
                        textView.setX(seekBar.getX() + val + seekBar.getThumbOffset() / 2);
                        //textView.setY(100); just added a value set this properly using screen with height aspect ratio , if you do not set it by default it will be there below seek bar 
    
                    }
    

    或者您可以将 Paint 与您的自定义 SeekBar 类一起使用,而无需任何 TextView

    创建一个类

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.widget.SeekBar;
    
    
    public class MySeekBar extends SeekBar {
        public MySeekBar (Context context) {
            super(context);
        }
    
        public MySeekBar (Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public MySeekBar (Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        protected void onDraw(Canvas c) {
            super.onDraw(c);
            int thumb_x = (int) (( (double)this.getProgress()/this.getMax() ) * (double)this.getWidth());
            float middle = (float) (this.getHeight());
    
            Paint paint = new Paint();
            paint.setColor(Color.BLACK);
            paint.setTextSize(20);
            c.drawText(""+this.getProgress(), thumb_x, middle, paint);
        }
    }
    

    在您的 XML 中设置/创建您的 SeekBar

      <yourPackageName.MySeekBar
                android:id="@+id/my_seek_bar"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginTop="26dp"
                android:max="10"/>
    

    现在来自您的活动

    seekBar = (MySeekBar) findViewById(R.id.my_seek_bar);
    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        }
    
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }
    
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    });
    

    【讨论】:

    • 太棒了,谢谢!我认为文本视图的正确位置计算如下(Kotlin):val offset = (seekBar.width - seekBar.paddingLeft - seekBar.paddingRight) * progress / seekBar.max 然后textView.x = seekBar.x + seekBar.paddingLeft + offset
    • PS:加上textView.x = [...] - textView.width / 2 使文本视图居中。
    【解决方案2】:

    在你的 xml 文件中添加一个文本视图,你可以像这样使用 linrarlayout:

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <SeekBar
                android:id="@+id/seekBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:max="1000" />
    
            <TextView
                android:id="@+id/textView4"
                android:layout_width="80dp"
                android:layout_height="wrap_content"
                android:layout_weight="1" />
    
        </LinearLayout>
    

    在java文件中,改变seekbar的onProgressChanged方法中的文本视图文本:

        SeekBar sk = (SeekBar) findViewById(R.id.seekBar);
        sk.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                TextView t=(TextView)findViewById(R.id.textView4);
                t.setText(String.valueOf(i));
            }
    
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
    
            }
    
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
    
            }
        });
    

    【讨论】:

      【解决方案3】:

      使文本视图真正与拇指位置 X 的中心对齐

      @Override
      public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
          progressTextView.setText(String.valueOf(progress));
      
          int width = seekBar.getWidth() - seekBar.getPaddingLeft() - seekBar.getPaddingRight();
          int thumbPos = seekBar.getPaddingLeft() + width * seekBar.getProgress() / seekBar.getMax();
      
          progressTextView.measure(0, 0);
          int txtW = progressTextView.getMeasuredWidth();
          int delta = txtW / 2;
          progressTextView.setX(seekBar.getX() + thumbPos - delta);
      }
      

      【讨论】:

        【解决方案4】:

        试试我找到的这个离散搜索栏库here

        最简单的方法是使用 Materila Slider 为您添加值标签,而无需编写 textView 进行跟踪。

           <com.google.android.material.slider.Slider
                android:id="@+id/continuous_slider"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:valueFrom="0"
               android:stepSize="1"
                app:labelBehavior="withinBounds"
                android:valueTo="100"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"/>
        

        【讨论】:

          【解决方案5】:

          检查此library。您可以使用“单拇指到真范围搜索栏”。

          【讨论】:

          • 不错的发现。它说它已被弃用,但我会试一试
          【解决方案6】:

          对于大多数情况,公认的答案可能已经足够了。但是,如果您想要精确以使文本恰好位于搜索栏拇指的中间,则必须进行更多计算。这是因为文本的宽度不同。假设您要显示 0 到 150 之间的数字。188 的宽度将与 111 不同。因此,您显示的文本将始终向某一侧倾斜。

          解决这个问题的方法是测量文本的宽度,将其从搜索栏拇指的宽度中删除,然后将其除以 2,然后将其添加到已接受答案中给出的结果中。现在您不会关心数字范围有多大。代码如下:

           override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                              val value = progress * (seekBar.width - 2 * seekBar.thumbOffset) / seekBar.max
                              label.text = progress.toString()
                              label.measure(0, 0)
                              val textWidth =  label.measuredWidth
                              val firstRemainder = seekThumbWidth - textWidth
                              val result = firstRemainder / 2
                              label.x = (seekBar.x + value + result)
                          }
          

          【讨论】:

            猜你喜欢
            • 2020-04-05
            • 2012-04-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-16
            相关资源
            最近更新 更多