I want Vertical seekBar like below image (for android 4.O+)). its in Google Play Music App.
i have tried below way: but i can't set hight & width
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rotation="270"
/>
i want like below:
right now i have used this Stack Answer but its too hard to manage multiple vertical seekbar.
i am looking for better way than this.
EDIT:
i have used below code from iDroid Explorer's answer try to display vertical seek bar:
private void setupEqualizerFxAndUI() {
for (short i = 0; i < 5; i++) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.weight = 3;
LinearLayout row = new LinearLayout(this);
row.setOrientation(LinearLayout.VERTICAL);
row.setLayoutParams(layoutParams);
TextView minDbTextView = new TextView(this);
minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
minDbTextView.setText(i + " dB");
TextView maxDbTextView = new TextView(this);
maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
maxDbTextView.setText(i + " dB");
LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams1.weight = 2;
SeekBar bar = new SeekBar(this);
bar.setLayoutParams(layoutParams1);
bar.setMax(100);
bar.setProgress(20);
bar.setRotation(270);
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
row.addView(minDbTextView);
row.addView(bar);
row.addView(maxDbTextView);
mLinearLayout.addView(row);
}
}
but it looks like below: indicator is not showing.
if i use only one seekBar then its look like below:
it same like use : android:rotation="270" in layout file.
iDroid Explorer's code is great and helped me a lot getting the job done, however it is missing some parts. Here's my hacked version, it works great for me and I hope it does for you too.
public class VerticalSeekBar extends SeekBar {
protected OnSeekBarChangeListener changeListener;
protected int x, y, z, w;
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);
}
#Override
protected synchronized void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
this.x = w;
this.y = h;
this.z = oldw;
this.w = oldh;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
#Override
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:
setSelected(true);
setPressed(true);
if (changeListener != null) changeListener.onStartTrackingTouch(this);
break;
case MotionEvent.ACTION_UP:
setSelected(false);
setPressed(false);
if (changeListener != null) changeListener.onStopTrackingTouch(this);
break;
case MotionEvent.ACTION_MOVE:
int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
if (changeListener != null) changeListener.onProgressChanged(this, progress, true);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
#Override
public synchronized void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
changeListener = listener;
}
#Override
public synchronized void setProgress(int progress) {
if (progress >= 0)
super.setProgress(progress);
else
super.setProgress(0);
onSizeChanged(x, y, z, w);
if (changeListener != null) changeListener.onProgressChanged(this, progress, false);
}
}
Have you check the android Sample code of AudioFXDemo? If not then please check it and see whether it is helpful to you or not.
There is Equalizer which is same as Google Music app have.
Check below code in that Demo Example:
private void setupEqualizerFxAndUI() {
// Create the Equalizer object (an AudioEffect subclass) and attach it to our media player,
// with a default priority (0).
try {
System.out.println("setupEqualizerFxAndUI eEqualizer is: "+mEqualizer);
System.out.println("setupEqualizerFxAndUI mIRemoteService: "+mIRemoteService);
mEqualizer = new Equalizer(0,mIRemoteService.getAudioSessionId());
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (RuntimeException e) {
e.printStackTrace();
} // Error in this line
if(onOffBtn.isChecked()){
mEqualizer.setEnabled(true);
}
short bands = 5 ;
//System.out.println("bands are: "+bands);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
params.weight = 1;
LinearLayout newOne = new LinearLayout(this);
newOne.setLayoutParams(params);
newOne.setOrientation(LinearLayout.HORIZONTAL);
final short minEQLevel = mEqualizer.getBandLevelRange()[0];
final short maxEQLevel = mEqualizer.getBandLevelRange()[1];
//System.out.println("Minimum value::: "+minEQLevel);
//System.out.println("Maximum value::: "+maxEQLevel);
//VerticalSeekBar[] bar = new VerticalSeekBar[5];
for (short i = 0; i < bands; i++) {
final short band = i;
/* TextView freqTextView = new TextView(this);
freqTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);
freqTextView.setText((mEqualizer.getCenterFreq(band) / 1000) + " Hz");
newOne.addView(freqTextView);*/
LinearLayout row = new LinearLayout(this);
row.setOrientation(LinearLayout.VERTICAL);
TextView minDbTextView = new TextView(this);
minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
minDbTextView.setText((minEQLevel / 100) + " dB");
minDbTextView.setTextColor(0xff000000);
TextView maxDbTextView = new TextView(this);
maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
maxDbTextView.setText((maxEQLevel / 100) + " dB");
maxDbTextView.setTextColor(0xff000000);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 300);
layoutParams.setMargins(0, 10, 0, 10);
//--------------------------
// setClassicTone(maxEQLevel, minEQLevel);
VerticalSeekBar bar = new VerticalSeekBar(this);
bar = new VerticalSeekBar(this);
bar.setLayoutParams(layoutParams);
bar.setMax(maxEQLevel - minEQLevel);
bar.setProgress(mEqualizer.getBandLevel(band));
//bar.setMax(3000);
//bar.setProgress(mEqualizer.getBandLevel(band)+1500);
bar.setPadding(0, 10, 0, 10);
//bar.setProgressDrawable(R.drawable.scrubber_progress_horizontal_holo_light);
bar.setProgressDrawable(getResources().getDrawable(R.drawable.scrubber_progress_horizontal_holo_light));
bar.setThumb(getResources().getDrawable(R.drawable.scrubber_control_selector_holo));
//System.out.println("Progress:::"+(mEqualizer.getBandLevel(band)));
//bar[i].setProgress((maxEQLevel-minEQLevel)/2);
mEqualizer.setBandLevel(band,(short) ((maxEQLevel-minEQLevel)));
//System.out.println("Presets are: "+mEqualizer.getNumberOfPresets()+" And name is: "+mEqualizer.getPresetName(i));
//mEqualizer.setBandLevel(band, level)
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
System.out.println("Seek bar change ");
presetsSpinner.setSelection(0);
mEqualizer.setBandLevel(band, (short) (progress + minEQLevel));
}
public void onStartTrackingTouch(SeekBar seekBar) {}
public void onStopTrackingTouch(SeekBar seekBar) {}
});
row.addView(maxDbTextView);
row.addView(bar);
row.addView(minDbTextView);
newOne.addView(row, params);
}
equalizerLayout.addView(newOne);
}
And the VerticalSeekBar is the class as below:
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;
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);
}
#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:
setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}
Hope above code help you. If not then let me know.
Enjoy Coding... :)
Apparently, equalizer is not part of Google Play Music, but rather a separate application called MusicFX (com.android.musicfx):
I/ActivityManager(536): START u0 {act=android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL cmp=com.android.musicfx/.Compatibility$Redirector (has extras)} from pid 4800
I/ActivityManager(536): START u0 {act=android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL flg=0x2000000 cmp=com.android.musicfx/.ActivityMusic (has extras)} from pid 4867
I/ActivityManager(536): Displayed com.android.musicfx/.ActivityMusic: +293ms (total +315ms)
The source code of MusicFX is available from Android repository.
Hope this helps.
Related
I was customized android default seek bar to show in vertically and using in fragments go get some feedback from user.
After first launch it is showing properly. But Once I submitted my first feedback I am relaunching the activity with fragments which contains my customized Vertical Seek Bar.
At that time thumb in Vertical Seekbar is coming to "0" but progress is not coming to "0" and showing some progress. :(
Below i am adding my Vertical Seek bar code please suggest me if i missed any thing .
public class VerticalSeekBar extends SeekBar {
private int mLastProgress = 0;
private OnSeekBarChangeListener mOnChangeListener;
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public synchronized int getMaximum() {
return getMax();
}
#Override
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mOnChangeListener != null) {
mOnChangeListener.onStartTrackingTouch(this);
}
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_MOVE:
super.onTouchEvent(event);
int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
// Ensure progress stays within boundaries
if (progress < 0) {
progress = 0;
}
if (progress > getMax()) {
progress = getMax();
}
setProgress(progress); // Draw progress
if (progress != mLastProgress) {
// Only enact listener if the progress has actually changed
mLastProgress = progress;
if (mOnChangeListener != null) {
mOnChangeListener.onProgressChanged(this, progress, true);
}
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_UP:
if (mOnChangeListener != null) {
mOnChangeListener.onStopTrackingTouch(this);
}
setPressed(false);
setSelected(false);
break;
case MotionEvent.ACTION_CANCEL:
super.onTouchEvent(event);
setPressed(false);
setSelected(false);
break;
}
return true;
}
public synchronized void setMaximum(int maximum) {
setMax(maximum);
}
#Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener onChangeListener) {
this.mOnChangeListener = onChangeListener;
}
public synchronized void setProgressAndThumb(int progress) {
setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
if (progress != mLastProgress) {
mLastProgress = progress;
if (mOnChangeListener != null) {
mOnChangeListener.onProgressChanged(this, progress, true);
}
}
}
public synchronized void setMyProgress(int progress) {
setProgress(progress);
}
}
Finally i got the solution for my problem.
In .xml while creating vertical seekBar I used android:progressDrawable="#drawable/seek" but in seek.xml i forgot to declare titles as
item android:id="#android:id/secondaryProgress",
item android:id="#android:id/background" and
item android:id="#android:id/progress".
I have one Vertical Seekbar in my android project. Vertical Seekbar is initialized in onCreate Method:
verticalSeekBar1 = (VerticalSeekBar) findViewById(R.id.verticalSeekbar1);
verticalSeekBar1.setOnSeekBarChangeListener(Listener1);
And I have to implement OnSeekBarChangeListener interface as shown below
private SeekBar.OnSeekBarChangeListener Listener1 = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar arg0, int seekBarLevel, boolean changedByUser) {
verticalSeekBar1.setProgress(seekBarLevel);
Log.e(TAG, "onProgressChanged: UserChnagedSeekbar :: "+changedByUser);
if (changedBySpinner){
mSpinner.setSelection(0);
}
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
};
changedByUser is always return false. Whether I changed Seekbar or not. Please help me to get out of this problem. Thank you in advance.
My Custom Vertical Seekbar Class code is
public class VerticalSeekBar extends SeekBar {
private Context mContext;
public VerticalSeekBar(Context context) {
super(context);
init(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
mContext=context;
}
protected void onSizeChanged(int w, int h, int oldWidth, int oldHeight) {
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) {
Paint paint=new Paint();
paint.setColor(Color.DKGRAY);
paint.setStrokeWidth(2.0f);
Rect rect=new Rect(0,0,getMeasuredWidth(),getMeasuredHeight());
//c.drawRect(rect,paint);
int vWidth=getMeasuredWidth();
int vHeight=getMeasuredHeight();
float startPointY=83;
float middlePointY = (vHeight)/2;
float lastPointY=vHeight-83;
paint.setColor(Color.DKGRAY);
c.drawLine(rect.left,startPointY,rect.centerX(),startPointY,paint);
c.drawLine(rect.left,middlePointY,rect.centerX(),middlePointY,paint);
c.drawLine(rect.left,lastPointY,rect.centerX(),lastPointY,paint);
paint.setColor(Color.DKGRAY);
float x=((vHeight/2)-startPointY)/3;
float f10dbPoint=x+startPointY;
float f5dbPoint=(2*x)+startPointY;
float fm5dbPoint=(vHeight/2)+x;
float fm10dbPoint=(vHeight/2)+(2*x);
float startX=rect.left+32;
c.drawLine(startX,f10dbPoint,rect.centerX(),f10dbPoint,paint);
c.drawLine(startX,f5dbPoint,rect.centerX(),f5dbPoint,paint);
c.drawLine(startX,fm5dbPoint,rect.centerX(),fm5dbPoint,paint);
c.drawLine(startX,fm10dbPoint,rect.centerX(),fm10dbPoint,paint);
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);
Log.i("Progress",getProgress()+"");
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
public void updateThumb(){
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
}
I didn't got the answer that why it's returning value false. But I got the alternate solution to know weather user changed seekbar value or u have changed seekbar value coding. I was changing seekbar value using depending on spinner value. So take variable
boolean changedBySpinner=false;
Inside Spinner ItemClickListener make it true
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
changedBySpinner=true;
}
});
set touchClickListener on the seekbar (vertical seekbar)
verticalSeekBar1.setOnTouchListener((View.OnTouchListener) this);
Inside onTouchMethod make that variable true
changedBySpinner=false;
And inside seekbarChangeListener add below code
private SeekBar.OnSeekBarChangeListener Listener1 = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar arg0, int seekBarLevel, boolean changedByUser) {
if (!changedBySpinner){
mSpinner.setSelection(0);
}
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
};
Perform your action which wanted to, inside if block. Like I am setting spinner value to 0th element.
Well, this is just an alternate solution. If you are facing the same problem you can use it.
I am designing a customview for the seats in the theater.For x large phones it is working smoothly.But in lower density devices it is hard to work with.
my customview.java
public class SeatView extends ImageView {
float dim;
int status;
Canvas canvas1;
boolean sela=false,ds=false,ua=false;
Bitmap selectedAvailableImage,deselectedAvailableImage,unavailableImage;
Drawable selectedAvailable,deselectedAvailable,unavailable;
SeatView seatView;
public SeatView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SeatView,0, 0);
try {
dim = a.getDimension(R.styleable.SeatView_dim, 20f);
status=a.getInt(R.styleable.SeatView_status,1);
selectedAvailableImage=BitmapFactory.decodeResource(getResources(),R.drawable.seat_selected);
deselectedAvailableImage=BitmapFactory.decodeResource(getResources(),R.drawable.seat_available);
unavailableImage=BitmapFactory.decodeResource(getResources(),R.drawable.seat_unavailable);
selectedAvailable=getResources().getDrawable(R.drawable.seat_selected);
deselectedAvailable=getResources().getDrawable(R.drawable.seat_available);
unavailable=getResources().getDrawable(R.drawable.seat_unavailable);
//selectedAvailable.setBounds(100,100,100,100);
//deselectedAvailable.setBounds(10,10,10,10);
//unavailable.setBounds(10,10,10,10);
} finally {
a.recycle();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP){
if(status==0){
status=1;
invalidate();
}else if(status==1){
status=0;
invalidate();
}
}
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(50,50);
}
public void setAvailable(){
status=1;
invalidate();
}
public void setDisabled(){
status=2;
invalidate();
}
public void setSelected(){
status=0;
invalidate();
}
public int getSeatStatus(){
return status;
}
public void init(Canvas canvas){
switch (status){
case 0:
//sela=true;ds=false;ua=false;
//setImageDrawable(selectedAvailable);
canvas.drawBitmap(selectedAvailableImage,0,0,null);
break;
case 1:
//sela=false;ds=true;ua=false;
//setImageDrawable(deselectedAvailable);
canvas.drawBitmap(deselectedAvailableImage,0,0,null);
break;
case 2:
//sela=false;ds=false;ua=true;
//setImageDrawable(unavailable);
canvas.drawBitmap(unavailableImage,0,0,null);
break;
default: //setImageDrawable(deselectedAvailable);
canvas.drawBitmap(deselectedAvailableImage,0,0,null);
break;
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
init(canvas);
}
}
and my mainactivity.java
public class MainActivity extends AppCompatActivity {
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ButterKnife.bind(this);
TableLayout tableLayout=(TableLayout)findViewById(R.id.tblelay);
// Toast.makeText(getApplicationContext(),seatView.getSeatStatus()+"",Toast.LENGTH_LONG).show();
//LinearLayout relativeLayout=(LinearLayout) findViewById(R.id.tblelay);
for (int j=0;j<20;j++){
TableRow tableRow=new TableRow(this);
for (int i=1;i<20;i++){
SeatView seatView=new SeatView(this,null);
seatView.setAvailable();
seatView.setId(i);
if(i%5==0){
seatView.setVisibility(View.INVISIBLE);
}
if(seatView.getParent()!=null)
((ViewGroup)seatView.getParent()).removeView(seatView); // <- fix
if(tableRow.getParent()!=null)
((ViewGroup)tableRow.getParent()).removeView(tableRow);
/* if(i>0){
RelativeLayout.LayoutParams layoutParams=new Rela tiveLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.RIGHT_OF, (i-1));
}*/
tableRow.addView(seatView);
}
tableLayout.addView(tableRow);}
}
}
click here for screenshot
I am trying to create a ProgresBar that looks like the following:
So far, I have created an object which extends ProgressBar, and now I am trying to figure out what my next step is.
I know that I need to override onDraw() with some logic that will decide how many squares to color in. This is trivial.
What I don't know how to do is get these squares in the first place. How can I replace the default drawable, so when I add my custom bar in the layout I can see something like my image?
try this custom Drawable:
class ProgressDrawable extends Drawable {
private static final int NUM_RECTS = 10;
Paint mPaint = new Paint();
#Override
protected boolean onLevelChange(int level) {
invalidateSelf();
return true;
}
#Override
public void draw(Canvas canvas) {
int level = getLevel();
Rect b = getBounds();
float width = b.width();
for (int i = 0; i < NUM_RECTS; i++) {
float left = width * i / NUM_RECTS;
float right = left + 0.9f * width / NUM_RECTS;
mPaint.setColor((i + 1) * 10000 / NUM_RECTS <= level? 0xff888888 : 0xffbbbbbb);
canvas.drawRect(left, b.top, right, b.bottom, mPaint);
}
}
#Override
public void setAlpha(int alpha) {
}
#Override
public void setColorFilter(ColorFilter cf) {
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
and test it with the following in onCreate:
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
final ProgressBar pb = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
Drawable d = new ProgressDrawable();
pb.setProgressDrawable(d);
pb.setPadding(20, 20, 20, 0);
ll.addView(pb);
OnSeekBarChangeListener l = new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int newProgress = pb.getMax() * progress / seekBar.getMax();
Log.d(TAG, "onProgressChanged " + newProgress);
pb.setProgress(newProgress);
}
};
int[] maxs = {4, 10, 60, 110};
for (int i = 0; i < maxs.length; i++) {
SeekBar sb = new SeekBar(this);
sb.setMax(maxs[i]);
sb.setOnSeekBarChangeListener(l);
sb.setPadding(20, 20, 20, 0);
ll.addView(sb);
}
setContentView(ll);
I have a seekbar that I want to only allow changing with the thumb/handle portion. If the user taps anywhere else, I'd like that tap to be ignored.
Is there an inherant property to do this? If not, I already know I can set an onTouch listener and return true to "disable" it, but is there a way to detect when the thumb is tapped so that I can tell onTouch to return false in that case?
I assume you want to change thumb position via code, which is user restricted.so for that try this.may be could help you.
myseekBar.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
int originalProgress;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
originalProgress = seekBar.getProgress();
}
#Override
public void onProgressChanged(SeekBar seekBar, int arg1, boolean fromUser) {
if( fromUser == true){
seekBar.setProgress(originalProgress);
}
}
});
I had the same issue , I fixed using a simple logic to compare the new Progress X OldProgress.
This is my code to a VerticalSlider that just allow change value when user click over Thumb.
This is the trick:
int tempProgress = (getMax() - (int) (getMax() * event.getY() / getHeight()));
int diff = Math.abs(tempProgress - progress);
if ( diff > 7 && !isMoving) return true;
isMoving = true;
This is all component source:
package android.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class VerticalSeekBar extends SeekBar {
private OnSeekBarChangeListener onChangeListener;
private int progress = 0;
private Drawable mThumb;
private boolean isMoving;
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);
}
#Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener onChangeListener){
this.onChangeListener = onChangeListener;
}
public void setThumb(Drawable thumb) {
if (thumb != null) {
thumb.setCallback(this);
}
super.setThumb(thumb);
mThumb = thumb;
mThumb.setCallback(this);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if ( onChangeListener!= null)onChangeListener.onStartTrackingTouch(this);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_MOVE:
int tempProgress = (getMax() - (int) (getMax() * event.getY() / getHeight()));
int diff = Math.abs(tempProgress - progress);
if ( diff > 7 && !isMoving) return true;
isMoving = true;
progress = getMax() - (int) (getMax() * event.getY() / getHeight());
if(progress < 18) {progress = 18;}
if(progress > getMax()) {progress = getMax();}
setProgressAndThumb(progress);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_UP:
isMoving = false;
if ( onChangeListener!= null)onChangeListener.onStopTrackingTouch(this);
setPressed(false);
setSelected(false);
break;
case MotionEvent.ACTION_CANCEL:
isMoving = false;
super.onTouchEvent(event);
setPressed(false);
setSelected(false);
break;
}
return true;
}
public synchronized void setProgressAndThumb(int progress) {
setProgress(progress);
onSizeChanged(getWidth(), getHeight() , 0, 0);
if ( onChangeListener!= null) onChangeListener.onProgressChanged(this, progress, true);
}
#Override
public synchronized void setProgress(int progress) {
this.progress =progress;
super.setProgress(progress);
if ( onChangeListener !=null) onChangeListener.onProgressChanged(this, progress, true);
}
public synchronized void setMaximum(int maximum) {
setMax(maximum);
}
public synchronized int getMaximum() {
return getMax();
}
}
Regards!
// I solved this problem.
private int mOriginProgress;
private boolean mIsDrag;
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
mIsTouched = true;
mOriginProgress = seekBar.getProgress();
}
#Override
public void onProgressChanged(SeekBar seekBar, int p, boolean fromUser) {
if (mOriginProgress == p) {
return;
}
if (mIsDrag) {
// do something
} else {
if (Math.abs(mOriginProgress - p) > 5) {
seekBar.setProgress(mOriginProgress);
} else {
mIsDrag = true;
}
}
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mIsDrag = false;
}