Android 在seekbar中创建垂直线

Android 在seekbar中创建垂直线,android,android-canvas,paint,android-seekbar,Android,Android Canvas,Paint,Android Seekbar,我正试图创造这样的东西。问题是如何创建靠近搜索栏的垂直线。我尝试了给定的代码,但seekbar行消失了。任何帮助都将不胜感激。这是我到目前为止所做的 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

我正试图创造这样的东西。问题是如何创建靠近搜索栏的垂直线。我尝试了给定的代码,但seekbar行消失了。任何帮助都将不胜感激。这是我到目前为止所做的

 public class MainActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            SeekBar sb = (SeekBar)findViewById(R.id.seekBar1);



            //Get the width of the main view.
            Display display = getWindowManager().getDefaultDisplay();
            Point displaysize = new Point();
            display.getSize(displaysize);
            int width = displaysize.x;




            //set the seekbar maximum (Must be a even number, having a remainder will cause undersirable results)
            //this variable will also determine the number of points on the scale.
            int seekbarmax = 10;




            int seekbarpoints = (width/seekbarmax); //this will determine how many points on the scale there should be on the seekbar


            //find the seekbar in the view, and set some behaviour properties
            SeekBar seekbar = (SeekBar)findViewById(R.id.seekBar1);


            //Set the seekbar to a max range of 10
            seekbar.setMax(seekbarmax);




            //Create a new bitmap that is the width of the screen
            Bitmap bitmap = Bitmap.createBitmap(width, 100, Bitmap.Config.ARGB_8888);
            //A new canvas to draw on.
            Canvas canvas = new Canvas(bitmap);


            //a new style of painting - colour and stoke thickness.
            Paint paint = new Paint();
            paint.setColor(Color.BLUE); //Set the colour to red
            paint.setStyle(Paint.Style.STROKE); //set the style
            paint.setStrokeWidth(1); //Stoke width


            Paint textpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            textpaint.setColor(Color.rgb(61, 61, 61));// text color RGB
            textpaint.setTextSize(28);// text size




            int point = 0; //initiate the point variable


            //Start a for loop that will loop seekbarpoints number of times.
            for (int i = 0; i < seekbarpoints; i++  ){




                if ((i%2)==0) {
                    //short line
                    point = point  + seekbarpoints;
                    canvas.drawLine(point, 30, point, 0, paint);
                    //drawLine(startx,startx,endy,endy)

            }


            //Create a new Drawable
            Drawable d = new BitmapDrawable(getResources(),bitmap);


            //Set the seekbar widgets background to the above drawable.
            seekbar.setProgressDrawable(d);





            }
        }

    }
公共类MainActivity扩展活动{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SeekBar sb=(SeekBar)findviewbyd(R.id.seekBar1);
//获取主视图的宽度。
Display Display=getWindowManager().getDefaultDisplay();
点显示大小=新点();
display.getSize(displaysize);
int width=displaysize.x;
//设置seekbar最大值(必须是偶数,余数将导致下旋结果)
//此变量还将确定刻度上的点数。
int seekbarmax=10;
int seekbarpoints=(width/seekbarmax);//这将确定seekbar上应有多少个刻度点
//在视图中找到seekbar,并设置一些行为属性
SeekBar SeekBar=(SeekBar)findViewById(R.id.seekBar1);
//将seekbar设置为最大范围10
seekbar.setMax(seekbarmax);
//创建一个与屏幕宽度相同的新位图
位图Bitmap=Bitmap.createBitmap(宽度,100,Bitmap.Config.ARGB_8888);
//一块新的画布。
画布=新画布(位图);
//一种新的绘画风格——颜色和厚度。
油漆=新油漆();
paint.setColor(Color.BLUE);//将颜色设置为红色
paint.setStyle(paint.Style.STROKE);//设置样式
paint.setStrokeWidth(1);//行程宽度
油漆文本油漆=新油漆(油漆.防油漆别名标志);
textpaint.setColor(Color.rgb(61,61,61));//文本颜色rgb
textpaint.setTextSize(28);//文本大小
int point=0;//初始化point变量
//启动一个for循环,该循环将循环seekbarpoints次。
对于(int i=0;i
我搜索了很长一段时间,只得到了一个数字的答案。因此我决定自己做。我采用了只包含步骤的解决方案,并通过添加间隔逻辑对其进行了扩展

public class MainActivity extends AppCompatActivity {

    private SeekbarWithIntervals SeekbarWithIntervals = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<String> seekbarIntervals = getIntervals();
        getSeekbarWithIntervals().setIntervals(seekbarIntervals);
    }

    private List<String> getIntervals() {
        return new ArrayList<String>() {{
            add("45");
            add("55");
            add("65");
            add("75");
            add("85");
            add("95");
        }};
    }

    private SeekbarWithIntervals getSeekbarWithIntervals() {
        if (SeekbarWithIntervals == null) {
            SeekbarWithIntervals = (SeekbarWithIntervals) findViewById(R.id.seekbarWithIntervals);
        }

        return SeekbarWithIntervals;
    }
}
请看下图

然后我成功地创建了一个seekbar,在seekbar上有间隔标签和垂直线。上图就是我所取得的成就

但是,在填充中很少有可以调整尺寸的优化

解决方案:

间隔的
xml
文件:

带间隔标签的搜索栏

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textViewInterval"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:textColor="#707070"/>
<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textViewVerticalLine"
    android:layout_width="1dp"
    android:layout_height="match_parent"
    android:background="@drawable/lines" />
然后自定义Seekbar类:

package com.example.abc.myapplication;

import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;

import com.example.abc.myapplication.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class SeekbarWithIntervals extends LinearLayout {
    private RelativeLayout RelativeLayout = null;
    private SeekBar Seekbar = null;
    private RelativeLayout Divider = null;
    private View verticalLine = null;

    private int WidthMeasureSpec = 0;
    private int HeightMeasureSpec = 0;

    public SeekbarWithIntervals(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        getActivity().getLayoutInflater()
                .inflate(R.layout.seekbar_with_intervals, this);
    }

    private Activity getActivity() {
        return (Activity) getContext();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        verticalLine = new View(getActivity());
        verticalLine.setLayoutParams(new LayoutParams(2, LayoutParams.MATCH_PARENT));
        verticalLine.setBackgroundColor(Color.BLACK);

        if (changed) {
            alignIntervals();

            // We've changed the intervals layout, we need to refresh.
            RelativeLayout.measure(WidthMeasureSpec, HeightMeasureSpec);
            RelativeLayout.layout(RelativeLayout.getLeft(), RelativeLayout.getTop(), RelativeLayout.getRight(), RelativeLayout.getBottom());
        }
    }

    private void alignIntervals() {
        int widthOfSeekbarThumb = getSeekbarThumbWidth();
        int thumbOffset = widthOfSeekbarThumb / 2;

        int widthOfSeekbar = getSeekbar().getWidth();
        int firstIntervalWidth = getRelativeLayout().getChildAt(0).getWidth();
        int remainingPaddableWidth = widthOfSeekbar - firstIntervalWidth - widthOfSeekbarThumb;

        int numberOfIntervals = getSeekbar().getMax();
        int maximumWidthOfEachInterval = remainingPaddableWidth / numberOfIntervals;

        alignFirstInterval(thumbOffset);
        alignIntervalsInBetween(maximumWidthOfEachInterval);
        alignLastInterval(thumbOffset, maximumWidthOfEachInterval);
    }

    private int getSeekbarThumbWidth() {
        return getResources().getDimensionPixelOffset(R.dimen.seekbar_thumb_width);
    }

    private void alignFirstInterval(int offset) {
        TextView firstInterval = (TextView) getRelativeLayout().getChildAt(0);
        firstInterval.setPadding(offset - 10, 0, 0, 0);

        TextView firstLine = (TextView) getDivider().getChildAt(0);
        firstLine.setPadding(offset + 10, 0, 0, 0);
    }

    private void alignIntervalsInBetween(int maximumWidthOfEachInterval) {
        int widthOfPreviousIntervalsText = 0;
        int widthOfPreviousLine = 0;

        // Don't align the first or last interval.
        for (int index = 1; index < (getRelativeLayout().getChildCount() - 1); index++) {
            TextView textViewInterval = (TextView) getRelativeLayout().getChildAt(index);
            int widthOfText = textViewInterval.getWidth();

            // This works out how much left padding is needed to center the current interval.
            //int leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 2) - (widthOfPreviousIntervalsText / 2) - (widthOfText / 2));
            int leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 2) - (widthOfPreviousIntervalsText / 2) - (widthOfText / index ) + index + 5 * 5);

            textViewInterval.setPadding(leftPadding, 0, 0, 0);

            widthOfPreviousIntervalsText = widthOfText;

            TextView textViewLine = (TextView) getDivider().getChildAt(index);
            int widthOfLine = textViewLine.getWidth();

            // This works out how much left padding is needed to center the current interval.
            leftPadding = (maximumWidthOfEachInterval + (index + (maximumWidthOfEachInterval / 10)) - (index * 4)); //Math.round(maximumWidthOfEachInterval + (widthOfLine ) + (widthOfPreviousLine ));
            //leftPadding = Math.round((maximumWidthOfEachInterval - (widthOfPreviousLine / index) - (widthOfPreviousLine / index) - (widthOfPreviousLine / index)) + 10);
            textViewLine.setPadding(leftPadding , 0, 0, 0);

            widthOfPreviousLine = widthOfLine;
        }
    }

    private void alignLastInterval(int offset, int maximumWidthOfEachInterval) {
        int lastIndex = getRelativeLayout().getChildCount() - 1;

        TextView lastInterval = (TextView) getRelativeLayout().getChildAt(lastIndex);
        int widthOfText = lastInterval.getWidth();

        int leftPadding = Math.round(maximumWidthOfEachInterval - widthOfText - offset);
        lastInterval.setPadding(leftPadding + 20, 0, 0, 0);

        TextView lastLine = (TextView) getDivider().getChildAt(lastIndex);
        leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 5) - (widthOfText / 5) - (widthOfText / 5 ) + 3 * 10);
        lastLine.setPadding(leftPadding , 0, 0, 0);

    }

    protected synchronized void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        WidthMeasureSpec = widthMeasureSpec;
        HeightMeasureSpec = heightMeasureSpec;

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public int getProgress() {
        return getSeekbar().getProgress();
    }

    public void setProgress(int progress) {
        getSeekbar().setProgress(progress);
    }

    public void setIntervals(List<String> intervals) {
        displayIntervals(intervals);
        getSeekbar().setMax(intervals.size() - 1);
    }

    private void displayIntervals(List<String> intervals) {
        int idOfPreviousInterval = 0;
        int idOfPreviousLine = 0;

        if (getRelativeLayout().getChildCount() == 0) {
            for (String interval : intervals) {
                TextView textViewInterval = createInterval(interval);
                alignTextViewToRightOfPreviousInterval(textViewInterval, idOfPreviousInterval);

                TextView textViewVerticaLine = createVerticalLine();
                alignTextViewToRightOfPreviousInterval(textViewVerticaLine, idOfPreviousLine);
                idOfPreviousLine = textViewVerticaLine.getId();

                idOfPreviousInterval = textViewInterval.getId();

                getRelativeLayout().addView(textViewInterval);
                getDivider().addView(textViewVerticaLine);

            }
        }
    }

    private TextView createInterval(String interval) {
        View textBoxView = (View) LayoutInflater.from(getContext())
                .inflate(R.layout.seekbar_with_intervals_labels, null);

        TextView textView = (TextView) textBoxView
                .findViewById(R.id.textViewInterval);

        textView.setId(View.generateViewId());
        textView.setText(interval);

        return textView;
    }

    private TextView createVerticalLine() {
        View textBoxView = (View) LayoutInflater.from(getContext())
                .inflate(R.layout.seekbar_vertical_lines, null);

        TextView textView = (TextView) textBoxView
                .findViewById(R.id.textViewVerticalLine);

        textView.setId(View.generateViewId());

        return textView;
    }


    private void alignTextViewToRightOfPreviousInterval(TextView textView, int idOfPreviousInterval) {
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        if (idOfPreviousInterval > 0) {
            params.addRule(RelativeLayout.RIGHT_OF, idOfPreviousInterval);
        }

        textView.setLayoutParams(params);
    }

    public void setOnSeekBarChangeListener(OnSeekBarChangeListener onSeekBarChangeListener) {
        getSeekbar().setOnSeekBarChangeListener(onSeekBarChangeListener);
    }

    private RelativeLayout getRelativeLayout() {
        if (RelativeLayout == null) {
            RelativeLayout = (RelativeLayout) findViewById(R.id.intervals);
        }

        return RelativeLayout;
    }

    private SeekBar getSeekbar() {
        if (Seekbar == null) {
            Seekbar = (SeekBar) findViewById(R.id.seekbar);
        }

        return Seekbar;
    }

    private RelativeLayout getDivider() {

        if (Divider == null) {
            Divider = (RelativeLayout) findViewById(R.id.fl_divider);
        }

        return Divider;
    }
}
package com.example.abc.myapplication;
导入java.util.List;
导入java.util.concurrent.locks.ReadWriteLock;
导入com.example.abc.myapplication.R;
导入android.app.Activity;
导入android.content.Context;
导入android.graphics.Color;
导入android.util.AttributeSet;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.widget.LinearLayout;
导入android.widget.RelativeLayout;
导入android.widget.SeekBar;
导入android.widget.SeekBar.onseekbarchaneglistener;
导入android.widget.TextView;
公共类seekbarwithinterval扩展线性布局{
private RelativeLayout RelativeLayout=null;
私有SeekBar SeekBar=null;
私有RelativeLayout除法器=null;
私有视图verticalLine=null;
私有int-WidthMeasureSpec=0;
私有int HeightMeasureSpec=0;
公共seekbarwithinterval(上下文上下文,属性集属性集){
super(上下文、属性集);
}
@凌驾
充气时受保护的空隙(){
超级充气();
getActivity().GetLayoutFlater()
.充气(R.layout.seekbar_与_间隔,此);
}
私有活动getActivity(){
返回(活动)getContext();
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
超级在线布局(更改,l,t,r,b);
verticalLine=新视图(getActivity());
verticalLine.setLayoutParams(新的LayoutParams(2,LayoutParams.MATCH_PARENT));
黄花牡丹色(黑色);
如果(更改){
对齐间隔();
//我们已经更改了间隔布局,需要刷新。
相对长度测量(宽度测量、高度测量);
RelativeLayout.layout(RelativeLayout.getLeft(),RelativeLayout.getTop(),RelativeLayout.getRight(),RelativeLayout.getBottom());
}
}
私有空间间隔(){
int-widthOfSeekbarThumb=getSeekbarThumbWidth();
int thumbOffset=搜索半径的宽度/2;
int-widthOfSeekbar=getSeekbar().getWidth();
int firstIntervalWidth=getRelativeLayout().getChildAt(0.getWidth();
int remainingPaddableWidth=搜索栏宽度-第一间隔宽度-搜索栏宽度;
int numberofinterval=getSeekbar().getMax();
int MaximumWidthOfAchinterval=剩余可填充宽度/间隔数;
对齐第一间隔(指偏移);
中间对齐间隔(最大值
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/seekbar_drawable_frost" />
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/seekbar_drawable_frost_progress" />

</layer-list>