网上有很多VerticalSeekbar,继承AbsSeekBar, 适用于UI固定的情况;
如果程序要自适应屏幕旋转,竖屏的时候用水平seekbar, 垂直的时候用VerticalSeekBar, 会出现旋转之后seekbar是两个不同的id, onProgressChanged无法收到 VerticalSeekbar 发过来的数据;
VerticalSeekbar代码如下:`
public class VerticalSeekBar extends SeekBar {
private String TAG = "VerticalSeekBar";
public VerticalSeekBar(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
//监听器用父类的;
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener l) {
mOnSeekBarChangeListener = l;
}
void onStartTrackingTouch() {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStartTrackingTouch(this);
}
}
void onStopTrackingTouch() {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStopTrackingTouch(this);
}
}
void onProgressRefresh(float scale, boolean fromUser) {
Drawable thumb = mThumb;
if (thumb != null) {
setThumbPos(getHeight(), thumb, scale, Integer.MIN_VALUE);
invalidate();
}
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, getProgress(),
fromUser);
}
}
private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
//Log.e(TAG, "setThumbPos scale = " + scale + ", w = " + w );
int available = w - getPaddingLeft() - getPaddingRight();
int thumbWidth = thumb.getIntrinsicWidth();
int thumbHeight = thumb.getIntrinsicHeight();
available -= thumbWidth;
available += getThumbOffset() * 2;
int thumbPos = (int) (scale * available);
int topBound, bottomBound;
if (gap == Integer.MIN_VALUE) {
Rect oldBounds = thumb.getBounds();
topBound = oldBounds.top;
bottomBound = oldBounds.bottom;
} else {
topBound = gap;
bottomBound = gap + thumbHeight;
}
thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
}
private Drawable mThumb;
@Override
public void setThumb(Drawable thumb) {
mThumb = thumb;
super.setThumb(thumb);
}
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);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
int i=0;
i=getMax() - (int) (getMax() * event.getY() / getHeight());
setProgress(i);
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}
MainActivity代码如下:
public class MainActivity extends Activity implements
SeekBar.OnSeekBarChangeListener
{
private Context m_fadbal_context;
private String TAG = "TEST";
private TextView m_Balance_TextView;
private TextView m_Fader_TextView;
private SeekBar m_FaderSeekBar;
private SeekBar m_BalanceSeekBar;
// ------
private RelativeLayout m_floatLayout;
private RelativeLayout m_top_title_Layout;
private View m_float_view;
private WindowManager windowManager;
private LayoutParams layoutParams, layoutParams_center;
private int m_nBallWidth, m_nBallRadius;
private boolean m_bLayoutTouchDown = false;
private static boolean m_bFloatViewDisplayed = false;
static float y0 = 0.0f, x0 = 0.0f;
float delt_x = 0.0f, delt_y = 0.0f;
private int m_nStatusBarHeight = 0;
int m_nViewMove_x = 0, m_nViewMove_y = 0;
public static boolean m_bCenterWinDisplayed = false;
private float m_center_x = 0.0f;
private float m_center_y = 0.0f;
private float m_action_w = 0.0f;
private float m_action_h = 0.0f;
private float m_action_left = 0.0f;
private float m_action_top = 0.0f;
private float m_action_right = 0.0f;
private float m_action_bottom = 0.0f;
private float m_fMoveStep = 0.0f;
private static int m_nFader = 10;
private static int m_nBalance = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initActivity();
}
public void onStart() {
super.onStart();
}
@Override
public synchronized void onResume() {
super.onResume();
getFloatLayoutRect();
}
@Override
public synchronized void onPause() {
super.onPause();
}
public void initActivity() {
setContentView(R.layout.test);
m_fadbal_context = this;
m_Balance_TextView = (TextView) findViewById(R.id.balance_value);
m_Fader_TextView = (TextView) findViewById(R.id.fader_value );
m_FaderSeekBar = (SeekBar) findViewById(R.id.fader_seek_bar);
m_BalanceSeekBar = (SeekBar) findViewById(R.id.balance_seek_bar);
m_FaderSeekBar.setMax(20);
m_FaderSeekBar.setProgress( m_nFader );
m_BalanceSeekBar.setMax(20);
m_BalanceSeekBar.setProgress( m_nBalance );
//Log.e(TAG, "rec: fad =" + m_nFader + ", bal = " + m_nBalance );
m_FaderSeekBar.setOnSeekBarChangeListener((OnSeekBarChangeListener) this);
m_BalanceSeekBar.setOnSeekBarChangeListener((OnSeekBarChangeListener) this);
// ------------------------------------------------------------------------------------
windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);
if( m_float_view == null )
m_float_view = LayoutInflater.from(this).inflate(R.layout.floating, null);
Bitmap m_float_view_bmp = BitmapFactory.decodeResource(
m_fadbal_context.getResources(), R.drawable.ball);
m_nBallWidth = m_float_view_bmp.getWidth();
m_nBallRadius = (int) ( m_nBallWidth >> 1 );
m_float_view_bmp.recycle();
/*
* LayoutParams.TYPE_SYSTEM_ERROR:保证该悬浮窗所有View的最上层
* LayoutParams.FLAG_NOT_FOCUSABLE:该浮动窗不会获得焦点,但可以获得拖动
* PixelFormat.TRANSPARENT:悬浮窗透明
*/
layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_SYSTEM_ERROR,
LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
m_top_title_Layout = (RelativeLayout) findViewById(R.id.setting_top_bar_layout);
m_floatLayout = (RelativeLayout) findViewById(R.id.float_layout);
m_floatLayout.setOnTouchListener(new OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event) {
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
{
m_nViewMove_x = (int) event.getRawX();
m_nViewMove_y = (int) event.getRawY() - m_nStatusBarHeight;
if( m_nViewMove_x > m_action_left && m_nViewMove_x < m_action_right
&& m_nViewMove_y > m_action_top && m_nViewMove_y < m_action_bottom )
{
refreshView( m_nViewMove_x, m_nViewMove_y );
m_nBalance = (int)( ( m_nViewMove_x - m_action_left ) / m_fMoveStep );
m_nFader = (int)( 20 - ( m_nViewMove_y - m_action_top ) / m_fMoveStep ) ;
updateFaderSeekBarText();
m_FaderSeekBar.setProgress( m_nFader );
updateBalanceSeekBarText();
m_BalanceSeekBar.setProgress(m_nBalance);
}
}
break;
}
return false;
}
});
m_float_view.setOnTouchListener(new OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event) {
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN: // 按下事件,记录按下时手指在悬浮窗的XY坐标值
{
m_bLayoutTouchDown = true;
}
break;
case MotionEvent.ACTION_MOVE:
{
m_nViewMove_x = (int) event.getRawX();
m_nViewMove_y = (int) event.getRawY() - m_nStatusBarHeight;
if( m_nViewMove_x < m_action_left )
m_nViewMove_x = (int)m_action_left;
if( m_nViewMove_x > m_action_right )
m_nViewMove_x = (int)m_action_right;
if( m_nViewMove_y < m_action_top )
m_nViewMove_y = (int)m_action_top;
if( m_nViewMove_y > m_action_bottom )
m_nViewMove_y = (int)m_action_bottom;
refreshView( m_nViewMove_x, m_nViewMove_y );
// 转成fader/balance
m_nBalance = (int)( ( m_nViewMove_x - m_action_left ) / m_fMoveStep );
m_nFader = (int)( 20 - ( m_nViewMove_y - m_action_top ) / m_fMoveStep ) ;
updateFaderSeekBarText();
m_FaderSeekBar.setProgress( m_nFader );
updateBalanceSeekBarText();
m_BalanceSeekBar.setProgress(m_nBalance);
}
break;
case MotionEvent.ACTION_UP: {
m_bLayoutTouchDown = false;
}
break;
}
return true;
}
});
// -----------------------------------------------------------------------
}
private Timer m_IdelTimer = null;
private MyIdelTimerTask m_IdelTimerTask = null;
private long m_lInterval = 200;
private final int GET_PARAMS = 0x20;
protected class MyIdelTimerTask extends TimerTask {
@Override
public void run() {
// TODO Auto-generated method stub
mHandler.sendEmptyMessage(GET_PARAMS);
}
} // end class
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case GET_PARAMS: {
if( m_nStatusBarHeight == 0 ){
View rootView = m_floatLayout.getRootView();
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
m_nStatusBarHeight = r.top;
}
int top_title_height = m_top_title_Layout.getHeight();
int float_top = m_floatLayout.getTop();
int float_bottom = m_floatLayout.getBottom();
int float_left = m_floatLayout.getLeft();
int float_right = m_floatLayout.getRight();
int canvas_w = float_right - float_left;
int canvas_h = float_bottom - float_top;
m_center_x = canvas_w / 2.0f;
m_center_y = canvas_h / 2.0f + top_title_height;
float min_canvas_w = Math.min(canvas_w, canvas_h);
m_action_w = min_canvas_w * 0.75f;
m_action_h = m_action_w;
m_fMoveStep = m_action_w / 21.0f;
m_action_left = m_center_x - m_action_w /2.0f ;
m_action_right = m_center_x + m_action_w /2.0f ;
m_action_top = m_center_y - m_action_h /2.0f ;
m_action_bottom = m_center_y + m_action_h /2.0f;
if (m_IdelTimer != null) {
m_IdelTimer.cancel();
m_IdelTimer = null;
}
if (m_IdelTimerTask != null) {
m_IdelTimerTask.cancel();
m_IdelTimerTask = null;
}
// -----
updateFloatLayout();
updateFaderSeekBarText();
m_FaderSeekBar.setProgress( m_nFader );
updateBalanceSeekBarText();
m_BalanceSeekBar.setProgress(m_nBalance);
}
break;
}
}
}; // end mHandler;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//save first
initActivity();
getFloatLayoutRect();
}
private void refreshFloatView() {
if (m_bFloatViewDisplayed) {
Log.e(TAG, "update m_float_view pos");
windowManager.updateViewLayout(m_float_view, layoutParams);
} else {
Log.e(TAG, "add m_float_view ");
windowManager.addView(m_float_view, layoutParams);
m_bFloatViewDisplayed = true;
}
}
public void refreshView(int x, int y) {
layoutParams.x = x - m_nBallRadius;
layoutParams.y = y - m_nBallRadius;
refreshFloatView();
}
public void getFloatLayoutRect() {
if (m_IdelTimer != null) {
m_IdelTimer.cancel();
m_IdelTimer = null;
}
if (m_IdelTimerTask != null) {
m_IdelTimerTask.cancel();
m_IdelTimerTask = null;
}
m_IdelTimer = new Timer();
m_IdelTimerTask = new MyIdelTimerTask();
m_IdelTimer.schedule(m_IdelTimerTask, m_lInterval, m_lInterval);
}
//根据m_nFader, m_nBalance更新 layout
public void updateFloatLayout()
{
int nViewMove_x = (int) ( m_action_left + m_fMoveStep * m_nBalance );
int nViewMove_y = (int) ( m_action_top + ( m_action_h - m_fMoveStep * m_nFader ) );
refreshView( nViewMove_x, nViewMove_y );
}
@Override
public void onProgressChanged(SeekBar seekbar, int pos, boolean arg2) {
// TODO Auto-generated method stub
if(seekbar.getId() == R.id.fader_seek_bar)
{
m_nFader = pos;
String temp_str = "";
if( (m_nFader - 10) > 0 )
temp_str = "+" + Integer.toString( m_nFader - 10 );
else
temp_str = Integer.toString( m_nFader - 10 );
m_Fader_TextView.setText( temp_str );
updateFloatLayout();
}
else if( seekbar.getId() == R.id.balance_seek_bar )
{
m_nBalance = pos;
String temp_str = "";
if( (m_nBalance - 10) > 0 )
temp_str = "+" + Integer.toString( m_nBalance - 10 );
else
temp_str = Integer.toString( m_nBalance - 10 );
m_Balance_TextView.setText( temp_str );
updateFloatLayout();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekbar) {
// TODO Auto-generated method stub
if(seekbar.getId() == R.id.fader_seek_bar)
{
}
else if( seekbar.getId() == R.id.balance_seek_bar )
{
}
}
@Override
public void onStopTrackingTouch(SeekBar seekbar) {
// TODO Auto-generated method stub
if(seekbar.getId() == R.id.fader_seek_bar)
{
}
else if( seekbar.getId() == R.id.balance_seek_bar )
{
}
}
public void updateFaderSeekBarText()
{
String temp_str = "";
if( (m_nFader - 10) > 0 )
temp_str = "+" + Integer.toString( m_nFader - 10 );
else
temp_str = Integer.toString( m_nFader - 10 );
m_Fader_TextView.setText( temp_str );
}
public void updateBalanceSeekBarText()
{
String temp_str = "";
if( (m_nBalance - 10) > 0 )
temp_str = "+" + Integer.toString( m_nBalance - 10 );
else
temp_str = Integer.toString( m_nBalance - 10 );
m_Balance_TextView.setText( temp_str );
}
public void onStop()
{
Log.e(TAG, "onStop");
windowManager.removeView(m_float_view);
m_bFloatViewDisplayed = false;
super.onStop();
}
}
链接地址:http://download.csdn.net/detail/yunchang789/9720273