使用 TextView 自定义搜索栏
Custom Seekbar with TextViews
我希望制作一个相当复杂的 CustomSeekBar。我找到的教程对我帮助不大,这对我来说是新领域。
我的目标是这样的:https://morgazmo99-yahoo-com.tinytake.com/sf/MjIwMjM2XzEzNzI5MzQ
我需要所有获取、设置、侦听和更新代码都包含在我的 CustomSeekBar class 中。 textViewA 和 textViewB 应该通过覆盖的 onProgressChanged 方法自动更新,尽管每个还需要一个 OnClickListener 来向这些视图添加额外的数据..
我想我很接近,但我不知道如何将视图封装到我的 CustomSeekBar class。我在尝试设置 TextView 时收到 NPE,我基本上理解原因,但我确定我希望 CustomSeekBar 组件管理这些 TextView。
我真的只是在寻求帮助,了解如何在我的自定义 class 中正确更新来自 OnProgressChanged 的 TextView。代码如下:
我的 XML 目前看起来还不错..
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center of Gravity"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginStart="@dimen/seekbar_margin"
android:layout_marginLeft="@dimen/seekbar_margin"
android:layout_marginTop="14dp" />
<com.sample.myapp.CustomSeekBar
android:id="@+id/customseekBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewTitle"
android:progressDrawable="@android:color/transparent"
android:max="100"
android:progress="50"/>
<TextView
android:id="@+id/textViewA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/customseekBar"
android:layout_marginStart="@dimen/seekbar_margin"
android:layout_marginLeft="@dimen/seekbar_margin"
android:layout_marginTop="@dimen/seekbar_text_padding"
android:clickable="true"/>
<TextView
android:id="@+id/textViewB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/customseekBar"
android:layout_marginEnd="@dimen/seekbar_margin"
android:layout_marginRight="@dimen/seekbar_margin"
android:layout_marginTop="@dimen/seekbar_text_padding"
android:clickable="true"/>
</RelativeLayout>
我确实有一个 CustomSeekBar class 可以到达那里:
package com.sample.myapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.SeekBar;
public class CustomSeekBar extends SeekBar implements SeekBar.OnSeekBarChangeListener {
private Rect rect;
private Paint paint;
private int seekbar_height, textViewAPercentage, textViewBPercentage;
private String textViewTitleText, textViewAText, textViewBText;;
private TextView textViewA, textViewB, textViewTitle;
public CustomSeekBar(Context context) {
super(context);
setOnSeekBarChangeListener(this);
}
public CustomSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
setOnSeekBarChangeListener(this);
rect = new Rect();
paint = new Paint();
seekbar_height = 6;
}
public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnSeekBarChangeListener(this);
}
public void setTextViewTitleText(String string) {
this.textViewTitleText = string;
}
public String getTextA() {
return textViewAText;
}
public void setTextA(String string) {
this.textViewAText = string;
}
public String getTextB() {
return textViewBText;
}
public void setTextB(String string) {
this.textViewBText = string;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int seekBarMax = seekBar.getMax();
textViewAPercentage = (seekBarMax / progress) * 100;
textViewBPercentage = ((seekBarMax - progress) / seekBarMax) * 100;
String A, B;
if (textViewAText != null) A = String.valueOf(textViewAPercentage) + "\n" + textViewAText;
else A = String.valueOf(textViewAPercentage);
if (textViewBText != null) B = String.valueOf(textViewBPercentage) + "\n" + textViewBText;
else B = String.valueOf(textViewBPercentage);
textViewA = (TextView) findViewById(R.id.textViewA);
textViewB = (TextView) findViewById(R.id.textViewB);
textViewA.setText(A);
textViewB.setText(B);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
protected synchronized void onDraw(Canvas canvas) {
rect.set(0 + getThumbOffset(), (getHeight() / 2) - (seekbar_height / 2), getWidth() - getThumbOffset(), (getHeight() / 2) + (seekbar_height / 2));
paint.setColor(Color.GRAY);
canvas.drawRect(rect, paint);
if (this.getProgress() > 50) {
rect.set(getWidth() / 2, (getHeight() / 2) - (seekbar_height / 2), getWidth() / 2 + (getWidth() / 100) * (getProgress() - 50), getHeight() / 2 + seekbar_height / 2));
paint.setColor(Color.CYAN);
canvas.drawRect(rect, paint);
}
if (this.getProgress() < 50) {
rect.set(getWidth() / 2 - ((getWidth() / 100) * (50 - getProgress())), (getHeight() / 2) - (seekbar_height / 2), getWidth() / 2, getHeight() / 2 + (seekbar_height / 2));
paint.setColor(Color.CYAN);
canvas.drawRect(rect, paint);
}
super.onDraw(canvas);
}
}
使用以下代码
interface iSeekChangeListener {
public void onChange(String a, String b);
}
为您的 activity class 实现 iSeekChangeListener 并重写 onChange() 如下
@Override
public void onChange(String a, String b) {
textViewA.setText(a);
textViewB.setText(b);
}
在您的 CustomSeekBar class 中设置侦听器
public void setListener(iSeekChangeListener customSeekActivty) {
this.customSeekListener = customSeekActivty;
}
在您的 Activity 中您需要设置侦听器
customSeekBar.setListener(this);
在您的 CustomSeekBar 的 onProgressChange() 中
if (customSeekListener != null)
customSeekListener.onChange(A, B);
我希望制作一个相当复杂的 CustomSeekBar。我找到的教程对我帮助不大,这对我来说是新领域。
我的目标是这样的:https://morgazmo99-yahoo-com.tinytake.com/sf/MjIwMjM2XzEzNzI5MzQ
我需要所有获取、设置、侦听和更新代码都包含在我的 CustomSeekBar class 中。 textViewA 和 textViewB 应该通过覆盖的 onProgressChanged 方法自动更新,尽管每个还需要一个 OnClickListener 来向这些视图添加额外的数据..
我想我很接近,但我不知道如何将视图封装到我的 CustomSeekBar class。我在尝试设置 TextView 时收到 NPE,我基本上理解原因,但我确定我希望 CustomSeekBar 组件管理这些 TextView。
我真的只是在寻求帮助,了解如何在我的自定义 class 中正确更新来自 OnProgressChanged 的 TextView。代码如下:
我的 XML 目前看起来还不错..
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center of Gravity"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginStart="@dimen/seekbar_margin"
android:layout_marginLeft="@dimen/seekbar_margin"
android:layout_marginTop="14dp" />
<com.sample.myapp.CustomSeekBar
android:id="@+id/customseekBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewTitle"
android:progressDrawable="@android:color/transparent"
android:max="100"
android:progress="50"/>
<TextView
android:id="@+id/textViewA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/customseekBar"
android:layout_marginStart="@dimen/seekbar_margin"
android:layout_marginLeft="@dimen/seekbar_margin"
android:layout_marginTop="@dimen/seekbar_text_padding"
android:clickable="true"/>
<TextView
android:id="@+id/textViewB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/customseekBar"
android:layout_marginEnd="@dimen/seekbar_margin"
android:layout_marginRight="@dimen/seekbar_margin"
android:layout_marginTop="@dimen/seekbar_text_padding"
android:clickable="true"/>
</RelativeLayout>
我确实有一个 CustomSeekBar class 可以到达那里:
package com.sample.myapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.SeekBar;
public class CustomSeekBar extends SeekBar implements SeekBar.OnSeekBarChangeListener {
private Rect rect;
private Paint paint;
private int seekbar_height, textViewAPercentage, textViewBPercentage;
private String textViewTitleText, textViewAText, textViewBText;;
private TextView textViewA, textViewB, textViewTitle;
public CustomSeekBar(Context context) {
super(context);
setOnSeekBarChangeListener(this);
}
public CustomSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
setOnSeekBarChangeListener(this);
rect = new Rect();
paint = new Paint();
seekbar_height = 6;
}
public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnSeekBarChangeListener(this);
}
public void setTextViewTitleText(String string) {
this.textViewTitleText = string;
}
public String getTextA() {
return textViewAText;
}
public void setTextA(String string) {
this.textViewAText = string;
}
public String getTextB() {
return textViewBText;
}
public void setTextB(String string) {
this.textViewBText = string;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int seekBarMax = seekBar.getMax();
textViewAPercentage = (seekBarMax / progress) * 100;
textViewBPercentage = ((seekBarMax - progress) / seekBarMax) * 100;
String A, B;
if (textViewAText != null) A = String.valueOf(textViewAPercentage) + "\n" + textViewAText;
else A = String.valueOf(textViewAPercentage);
if (textViewBText != null) B = String.valueOf(textViewBPercentage) + "\n" + textViewBText;
else B = String.valueOf(textViewBPercentage);
textViewA = (TextView) findViewById(R.id.textViewA);
textViewB = (TextView) findViewById(R.id.textViewB);
textViewA.setText(A);
textViewB.setText(B);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
protected synchronized void onDraw(Canvas canvas) {
rect.set(0 + getThumbOffset(), (getHeight() / 2) - (seekbar_height / 2), getWidth() - getThumbOffset(), (getHeight() / 2) + (seekbar_height / 2));
paint.setColor(Color.GRAY);
canvas.drawRect(rect, paint);
if (this.getProgress() > 50) {
rect.set(getWidth() / 2, (getHeight() / 2) - (seekbar_height / 2), getWidth() / 2 + (getWidth() / 100) * (getProgress() - 50), getHeight() / 2 + seekbar_height / 2));
paint.setColor(Color.CYAN);
canvas.drawRect(rect, paint);
}
if (this.getProgress() < 50) {
rect.set(getWidth() / 2 - ((getWidth() / 100) * (50 - getProgress())), (getHeight() / 2) - (seekbar_height / 2), getWidth() / 2, getHeight() / 2 + (seekbar_height / 2));
paint.setColor(Color.CYAN);
canvas.drawRect(rect, paint);
}
super.onDraw(canvas);
}
}
使用以下代码
interface iSeekChangeListener {
public void onChange(String a, String b);
}
为您的 activity class 实现 iSeekChangeListener 并重写 onChange() 如下
@Override
public void onChange(String a, String b) {
textViewA.setText(a);
textViewB.setText(b);
}
在您的 CustomSeekBar class 中设置侦听器
public void setListener(iSeekChangeListener customSeekActivty) {
this.customSeekListener = customSeekActivty;
}
在您的 Activity 中您需要设置侦听器
customSeekBar.setListener(this);
在您的 CustomSeekBar 的 onProgressChange() 中
if (customSeekListener != null)
customSeekListener.onChange(A, B);