AppCompat风格的Rangebar(带有两个拇指的Seekbar)

时间:2016-01-05 10:42:57

标签: android material-design android-appcompat seekbar

我在Android上发现了一些关于范围栏(带有两个拇指的搜索栏)的问题,例如Android Seekbar with two thumbsworking with SeekBar with two thumbs。所有答案都指向自Material Design以及AppCompat发布以来看起来过时的组件。

我正在寻找的是一个看起来像带有两个拇指的AppCompatSeekBar的Rangebar。是否有任何可用的库或方法入侵平台SeekBar,以便可以重用可用资源?

1 个答案:

答案 0 :(得分:0)

这是我第一次回答这里的事情。 我创建了自己的自定义范围栏,如下所示。

创建以下文件。

RangeBar.java

function fib(n) {
  if (n <= 1) {
    return n;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

fib(10); // returns 55

}

和range_seekbar.xml

public class RangeBar extends FrameLayout{
int minVal = 0;
int maxVal = 100;
Context context;
ImageView leftThumb;
ImageView rightThumb;
View view;

int leftThumbPos = 0;
int rightThumbPos = 100;


public RangeBar(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    this.view = inflate(getContext(), R.layout.range_seekbar, null);
    addView(this.view);
}

public RangeBar(Context context){
    super(context);
    this.context = context;
    this.view = inflate(getContext(), R.layout.range_seekbar, null);
    addView(this.view);
}

public void create() {
    leftThumb = (ImageView)findViewById(R.id.left_thumb);
    rightThumb = (ImageView)findViewById(R.id.right_thumb);

    final View leftBar =  findViewById(R.id.left_bar);
    final View rightBar =  findViewById(R.id.right_bar);
    final View middleBar =  findViewById(R.id.middle_bar);
    final LinearLayout.LayoutParams leftBarLayoutParams = (LinearLayout.LayoutParams) leftBar.getLayoutParams();
    final LinearLayout.LayoutParams rightBarLayoutParams = (LinearLayout.LayoutParams) rightBar.getLayoutParams();
    final LinearLayout.LayoutParams middleBarLayoutParams = (LinearLayout.LayoutParams) middleBar.getLayoutParams();
    final LinearLayout llRangeSeekbar = (LinearLayout)findViewById(R.id.ll_range_seekbar);

    ((TextView)findViewById(R.id.tv_range_max)).setText(maxVal+"");
    ((TextView)findViewById(R.id.tv_range_min)).setText(minVal+"");

    leftThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_min)).getText()+"");
    rightThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_max)).getText()+"");

    leftThumb.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int diff = maxVal - minVal;
            if(diff < 0){
                diff = 100;
                minVal = 0;
                maxVal = 100;
            }
            float width = llRangeSeekbar.getWidth();
            float gap = leftThumb.getWidth();

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                leftThumb.bringToFront();
                return true;
            }else if (event.getAction() == MotionEvent.ACTION_MOVE ) {
                float temp1 = leftBarLayoutParams.weight;
                float temp2 = middleBarLayoutParams.weight;
                leftBarLayoutParams.weight += event.getX()/width;
                middleBarLayoutParams.weight = 1 - (leftBarLayoutParams.weight + rightBarLayoutParams.weight);

                int tempMaxVal = Integer.parseInt(((TextView)findViewById(R.id.tv_range_max)).getText()+"");
                int tempMinVal = (int)(diff*leftBarLayoutParams.weight + minVal);
                if(tempMinVal > tempMaxVal){
                    tempMinVal = tempMaxVal;
                }
                if(tempMinVal < minVal){
                    tempMinVal = minVal;
                }
                ((TextView)findViewById(R.id.tv_range_min)).setText(tempMinVal + "");

                if(middleBarLayoutParams.weight > gap/width && leftBarLayoutParams.weight >= 0){
                    leftBar.setLayoutParams(leftBarLayoutParams);
                    middleBar.setLayoutParams(middleBarLayoutParams);
                }else {
                    if(leftBarLayoutParams.weight < 0){
                        leftBarLayoutParams.weight = 0;
                        middleBarLayoutParams.weight = 1 - (rightBarLayoutParams.weight + leftBarLayoutParams.weight);
                    }else{
                        middleBarLayoutParams.weight = gap/width + (tempMaxVal - tempMinVal)/(1.0f*diff);
                        leftBarLayoutParams.weight = 1 - (middleBarLayoutParams.weight + rightBarLayoutParams.weight);
                    }
                    leftBar.setLayoutParams(leftBarLayoutParams);
                    middleBar.setLayoutParams(middleBarLayoutParams);
                }
                return true;
            }else if (event.getAction() == MotionEvent.ACTION_UP) {
                leftThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_min)).getText()+"");
                return true;
            }else
            {
                return false;
            }
        }
    });

    rightThumb.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int diff = maxVal - minVal;
            if(diff < 0){
                diff = 100;
                minVal = 0;
                maxVal = 100;
            }
            float width = llRangeSeekbar.getWidth();
            float gap = leftThumb.getWidth();

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                rightThumb.bringToFront();
                return true;
            }else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                float temp1 = middleBarLayoutParams.weight;
                float temp2 = rightBarLayoutParams.weight;

                rightBarLayoutParams.weight -= (event.getX()/width);
                middleBarLayoutParams.weight = 1 - (rightBarLayoutParams.weight + leftBarLayoutParams.weight);

                int tempMinVal = Integer.parseInt(((TextView)findViewById(R.id.tv_range_min)).getText()+"");
                int tempMaxVal = (int)(diff*(1 - rightBarLayoutParams.weight) + minVal);
                if(tempMaxVal < tempMinVal){
                    tempMaxVal = tempMinVal;
                }
                if(tempMaxVal > maxVal){
                    tempMaxVal = maxVal;
                }
                ((TextView)findViewById(R.id.tv_range_max)).setText(tempMaxVal+"");

                if(middleBarLayoutParams.weight > gap/width && rightBarLayoutParams.weight >= 0){
                    rightBar.setLayoutParams(rightBarLayoutParams);
                    middleBar.setLayoutParams(middleBarLayoutParams);
                }else{
                    if(rightBarLayoutParams.weight < 0){
                        rightBarLayoutParams.weight = 0;
                        middleBarLayoutParams.weight = 1 - (rightBarLayoutParams.weight + leftBarLayoutParams.weight);
                    }else {
                        middleBarLayoutParams.weight = gap/width + (tempMaxVal - tempMinVal)/(1.0f*diff);
                        rightBarLayoutParams.weight = 1 - (leftBarLayoutParams.weight + middleBarLayoutParams.weight);
                    }
                    rightBar.setLayoutParams(rightBarLayoutParams);
                    middleBar.setLayoutParams(middleBarLayoutParams);

                }
                return true;
            }else if (event.getAction() == MotionEvent.ACTION_UP) {
                rightThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_max)).getText()+"");
                return true;
            }
            else
            {
                return false;
            }
        }
    });
}


public int getMinVal() {
    return minVal;
}

public void setMinVal(int minVal) {
    this.minVal = minVal;
}

public int getMaxVal() {
    return maxVal;
}

public void setMaxVal(int maxVal) {
    this.maxVal = maxVal;
}


public int getLeftThumbPos() {
    return leftThumbPos;
}

public void setLeftThumbPos(int leftThumbPos) {
    this.leftThumbPos = leftThumbPos;
}

public int getRightThumbPos() {
    return rightThumbPos;
}

public void setRightThumbPos(int rightThumbPos) {
    this.rightThumbPos = rightThumbPos;
}

在活动中使用它们如下。

Test.java

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_height="match_parent">
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:gravity="center"
        android:id="@+id/ll_range_seekbar"
        android:layout_height="wrap_content">

        <View
            android:layout_width="0dp"
            android:layout_weight="0"
            android:id="@+id/left_bar"
            android:background="@color/light_grey"
            android:layout_height="1dp"/>
        <RelativeLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:id="@+id/middle_bar"
            android:layout_height="wrap_content">

            <View
                android:layout_width="match_parent"
                android:layout_centerVertical="true"
                android:id="@+id/middle_view"
                android:layout_toRightOf="@+id/left_thumb"
                android:layout_toLeftOf="@+id/right_thumb"
                android:background="@color/color_select_sky_blue"
                android:layout_height="1dp"/>
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/left_thumb"
                android:layout_alignParentLeft="true"
                android:src="@drawable/seek_thumb_normal"/>

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/right_thumb"
                android:layout_alignParentRight="true"
                android:src="@drawable/seek_thumb_normal"/>
        </RelativeLayout>

        <View
            android:layout_width="0dp"
            android:layout_weight="0"
            android:id="@+id/right_bar"
            android:background="@color/light_grey"
            android:layout_height="1dp"/>
    </LinearLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:id="@+id/tv_range_min"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:id="@+id/tv_range_max"/>
    </RelativeLayout>
</LinearLayout>

这是活动的布局文件。

的test.xml

public class Test extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);
        RangeBar rangeBar = (RangeBar) findViewById(R.id.rangebar);
        rangeBar.setMinVal(25);
        rangeBar.setMaxVal(50);
        rangeBar.create();
    }
}.