2009-03-10 31 views
17

Tôi đang cố gắng tìm một thanh tìm kiếm thẳng đứng với trình mô phỏng, nhưng tôi là loại bị kẹt. Tôi có thể lấy thanh tìm kiếm để hiển thị theo cách tôi muốn, và tôi có thể đạt được tiến bộ để làm những gì tôi muốn và tôi có thể sửa đổi onTouchEvent để nhận ngón tay cái theo chiều dọc thay vì theo chiều ngang. Những gì tôi không thể làm là lấy ngón tay cái để di chuyển bên ngoài của mặc định 29 pixel ngang mà không cần sử dụng setThumbOffset(). Điều này trong chính bản thân số không phải là vấn đề. Vấn đề là đến từ thực tế là tôi không hiểu thumbOffset ở tất cả - tôi đoán. Tôi nghĩ rằng tôi có thể (đúng cách) thay đổi kích thước các phụ tùng , mà tôi khá chắc chắn tôi không làm đúng. Hoặc có thể tôi có thể chỉ cần sử dụng thumbOffset nếu tôi có thể tìm ra. Vì tôi có thể tính toán tiến độ chính xác, tôi nghĩ tôi sẽ chỉ sử dụng hàm tuyến tính tuyến tính * (getTop() - getBottom()) của tiện ích con nhưng dường như không làm điều đó. Nhưng tôi không thể tìm ra bù đắp là tập trung xung quanh.Sửa đổi tiện ích con thanh tìm kiếm Android để hoạt động theo chiều dọc

Là một phần hơi sang một bên, tôi thực sự không chắc chắn nếu những gì tôi đang làm trong onSizeChanged() là lành mạnh hoặc nếu nó sẽ cắn tôi trong ass sau này trên.

Dưới đây là cách bố trí 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> 

Và lớp (bỏ qua các tin rác gỡ lỗi):

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; 
     } 

} 
+0

phải xem http://stackoverflow.com/a/28397583/3496570 và http://stackoverflow.com/a/28397530/ 3496570 – Nepster

Trả lời

9

Đối với API 11 and later, có thể sử dụng seekbar's XML thuộc tính (android:rotation="270") để có hiệu lực theo chiều dọc.

<SeekBar 
android:id="@+id/seekBar1" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:rotation="270"/> 

Đối với mức cũ API (ví dụ API10), sử dụng: https://github.com/AndroSelva/Vertical-SeekBar-Android hoặc thấy điều này sample here

Bạn cũng phải cập nhật nó là chiều cao & chiều rộng như đề nghị của Iftikhar

Theo thứ tự

seekBar.setLayoutParams(
       new ViewGroup.LayoutParams(convertDpToPixels(1.0f,mContext), ViewGroup.LayoutParams.WRAP_CONTENT)); 

// đã không kiểm tra ..

nơi

public static int convertDpToPixels(float dp, Context context){ 
    Resources resources = context.getResources(); 
    return (int) TypedValue.applyDimension(
      TypedValue.COMPLEX_UNIT_DIP, 
      dp, 
      resources.getDisplayMetrics() 
    ); 
} 
+0

theo cách này bạn không thể thay đổi chiều cao và chiều rộng thanh tìm kiếm, sau khi xoay chúng vẫn giống nhau. –

2

Hãy xem android source. Tôi nghĩ rằng bạn cần phải thay đổi ít nhất trackTouchEvent và có thể một vài nơi khác, nơi bạn cũng cần phải trao đổi các tọa độ x, y để tính đến vòng xoay của điều khiển.

0

Ông có thể rời khỏi seekbar như ngang, đặt nó trong một bố cục khung hình, sau đó xoay bố trí 90 độ trong java? âm thanh có thể thực hiện được ...

17

Tôi đã tạo một giải pháp hoạt động (ít nhất là cho tôi) và tạo ra một SeekBar dọc. http://hackskrieg.wordpress.com/2012/04/20/working-vertical-seekbar-for-android/

Mã này sẽ chọn/bỏ chọn ngón tay cái, di chuyển chính xác, cập nhật người nghe chính xác (chỉ khi tiến trình thay đổi!), Cập nhật/vẽ tiến trình chính xác, v.v.

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(); 
} 
} 

Tôi chỉ đặt SeekBar dọc này trong LinearLayout với layout_height được đặt thành FILL_PARENT và layout_width được đặt thành 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> 

LƯU Ý: Bạn phải đặt OnSeekBarChangeListener, nếu không tương tác với SeekBar sẽ tạo ra NullPointerException.

+0

@Technlx, ​​Bạn có sử dụng giải pháp này cho tiện ích trên màn hình chính không? – rxlky

+0

Nó sẽ cung cấp cho bạn lỗi cho đến khi bạn sử dụng "setOnSeekBarChangeListener" trong hoạt động java tương ứng của bạn hoặc lớp –

Các vấn đề liên quan