transparente - widget barra busqueda google android
Modificando el widget de la barra de búsqueda de Android para operar verticalmente (5)
¿Podría dejar la barra de búsqueda como horizontal, colocarla en un diseño de marco y luego girar el diseño 90 grados en el java? suena factible ...
Estoy tratando de conseguir una barra de búsqueda vertical con el emulador, pero estoy un poco atascado. Puedo hacer que la barra de búsqueda muestre lo que quiero, y puedo hacer que el progreso haga lo que quiera, y puedo modificar el onTouchEvent para que el pulgar vaya verticalmente en lugar de horizontalmente. Lo que no puedo hacer es conseguir que el pulgar se mueva fuera de los 29 píxeles horizontales predeterminados sin usar setThumbOffset (). Esto en sí mismo no es un problema. El problema proviene del hecho de que no comprendo el ThumbOffset en absoluto, supongo. Creo que podría (correctamente) cambiar el tamaño del widget, lo cual estoy bastante seguro de que no estoy haciendo bien. O tal vez podría usar el ThumbOffset si pudiera resolverlo. Como puedo calcular el progreso correctamente, pensé que solo usaría una función lineal de progress * (getTop () - getBottom ()) del widget, pero eso no parece funcionar. Pero no puedo entender en qué se centra el desplazamiento.
Dejando de lado, no estoy seguro de si lo que estoy haciendo en onSizeChanged () es sensato o si me va a morder en el trasero más adelante.
Aquí está el diseño main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.mobilsemantic.mobipoll.SlideBar
android:id="@+id/slide"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:max="100"
android:progress="0"
android:secondaryProgress="25" />
<Button android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Hello, I am a Button" />
<TextView android:id="@+id/tracking"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Y la clase (ignorar la chatarra de depuración):
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SeekBar;
public class SlideBar extends SeekBar {
private int oHeight = 320, oWidth = 29;
private int oProgress = -1, oOffset = -1;;
private float xPos = -1, yPos = -1;
private int top = -1, bottom = -1, left = -1, right = -1;
public SlideBar(Context context) {
super(context);
}
public SlideBar(Context context, AttributeSet attrs)
{
super(context, attrs);
oOffset = this.getThumbOffset();
oProgress = this.getProgress();
}
public SlideBar(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
protected synchronized void onMeasure(int widthMeasureSpec, intheightMeasureSpec)
{
int height = View.MeasureSpec.getSize(heightMeasureSpec);
oHeight = height;
this.setMeasuredDimension(oWidth, oHeight);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(h, w, oldw, oldh);
}
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
left = l;
right = r;
top = t;
bottom = b;
}
protected void onDraw(Canvas c)
{
c.rotate(90);
c.translate(0,-29);
super.onDraw(c);
}
public boolean onTouchEvent(MotionEvent event)
{
xPos = event.getX();
yPos = event.getY();
float progress = (yPos-this.getTop())/(this.getBottom()-this.getTop());
oOffset = this.getThumbOffset();
oProgress = this.getProgress();
Log.d("offset" + System.nanoTime(), new Integer(oOffset).toString());
Log.d("progress" + System.nanoTime(), new Integer(oProgress).toString());
float offset;
offset = progress * (this.getBottom()-this.getTop());
this.setThumbOffset((int)offset);
Log.d("offset_postsetprogress" + System.nanoTime(), new Integer(oOffset).toString());
Log.d("progress_postsetprogress" + System.nanoTime(), new Integer(oProgress).toString());
this.setProgress((int)(100*event.getY()/this.getBottom()));
return true;
}
}
Echa un vistazo a la fuente de Android . Creo que necesitas cambiar al menos trackTouchEvent y quizás hay algunos otros lugares donde también necesitas intercambiar las coordenadas x, y para tener en cuenta tu rotación del control.
He creado una solución que funciona (al menos para mí, de todos modos) y crea un SeekBar vertical. http://hackskrieg.wordpress.com/2012/04/20/working-vertical-seekbar-for-android/
Este código seleccionará / deseleccionará correctamente el pulgar, se moverá correctamente, actualizará el oyente correctamente (¡solo cuando el progreso cambie!), Actualizará / dibujará el progreso correctamente, etc.
public class VerticalSeekBar extends SeekBar {
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
private OnSeekBarChangeListener onChangeListener;
@Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener onChangeListener){
this.onChangeListener = onChangeListener;
}
private int lastProgress = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
onChangeListener.onStartTrackingTouch(this);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_MOVE:
// Calling the super seems to help fix drawing problems
super.onTouchEvent(event);
int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
// Ensure progress stays within boundaries of the seekbar
if(progress < 0) {progress = 0;}
if(progress > getMax()) {progress = getMax();}
// Draw progress
setProgress(progress);
// Only enact listener if the progress has actually changed
// Otherwise the listener gets called ~5 times per change
if(progress != lastProgress) {
lastProgress = progress;
onChangeListener.onProgressChanged(this, progress, true);
}
onSizeChanged(getWidth(), getHeight() , 0, 0);
onChangeListener.onProgressChanged(this, getMax() - (int) (getMax() * event.getY() / getHeight()), true);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_UP:
onChangeListener.onStopTrackingTouch(this);
setPressed(false);
setSelected(false);
break;
case MotionEvent.ACTION_CANCEL:
super.onTouchEvent(event);
setPressed(false);
setSelected(false);
break;
}
return true;
}
public synchronized void setProgressAndThumb(int progress) {
setProgress(getMax() - (getMax()- progress));
onSizeChanged(getWidth(), getHeight() , 0, 0);
}
public synchronized void setMaximum(int maximum) {
setMax(maximum);
}
public synchronized int getMaximum() {
return getMax();
}
}
Acabo de colocar este SeekBar vertical dentro de un LinearLayout con layout_height configurado en FILL_PARENT y layout_width establecido en WRAP_CONTENT.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.safetyculture.jsadroidtablet.VerticalSeekBar
android:id="@+id/calculatorVerticalSeekBar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="bottom"
android:max="4"
android:progress="2" />
</LinearLayout>
NOTA: Debe establecer un OnSeekBarChangeListener, de lo contrario, interactuar con SeekBar producirá NullPointerException.
Para API 11 and later
seekbar''s XML
API 11 and later
, puede usar seekbar''s XML
atributos seekbar''s XML
(android:rotation="270")
para el efecto vertical.
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rotation="270"/>
Para un nivel de API más antiguo (ex API10), use: https://github.com/AndroSelva/Vertical-SeekBar-Android o vea este ejemplo aquí
También tienes que actualizar su altura y anchura como lo sugiere Iftikhar
En orden
seekBar.setLayoutParams(
new ViewGroup.LayoutParams(convertDpToPixels(1.0f,mContext), ViewGroup.LayoutParams.WRAP_CONTENT));
// no he probado ...
dónde
public static int convertDpToPixels(float dp, Context context){
Resources resources = context.getResources();
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
resources.getDisplayMetrics()
);
}
Puede descargarlo en http://560b.sakura.ne.jp/android/VerticalSlidebarExample.zip , espero que esto pueda ayudarle.