ondraw taking too much ram in custom view repetition - android

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

Related

Why OnSeekBarChangeListener always returns boolean variable false?

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.

View distorted/blurred while using admob/amazon adds in Nexus 4

In Nexus 4, when showing adds (admob or amazon's), a view that is added and moved touching the screen becomes distorted. If ads are not shown, there is no problem with the view.
There isn't any problem either in the emulator or in a galaxy IV.
I think that the problem could be somewhat related to the chrome renderer and its use of the egl driver, but no idea how to solve it.
A test view code with admob:
public class TestAdmob extends ViewGroup {
private AdView adView;
private Rect drawRect;
private Test1 myView;
public TestAdmob(Activity context, String adUnitId) {
super(context);
myView = new Test1(context);
drawRect = new Rect(0, 0, 400, 400);
adView = new AdView(context);
adView.setAdSize(AdSize.SMART_BANNER);
adView.setAdUnitId(adUnitId);
adView.setAdListener(new AdListener() {
public void onAdLoaded() {
Log.d("Admob", "onAdLoaded");
requestLayout();
}
public void onAdFailedToLoad(int errorCode) { Log.d("Admob", "failedToLoad " + errorCode); }
public void onAdOpened() { Log.d("Admob", "adOpened"); }
public void onAdClosed() { Log.d("Admob", "adClosed"); }
public void onAdLeftApplication() { Log.d("Admob", "adLeftApp"); }
});
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
addView(adView);
adView.loadAd(adRequest);
}
private int getHeightAd() {
try { return adView.getAdSize().getHeightInPixels(adView.getContext()); }
catch (Exception e) {
e.printStackTrace();
return 200;
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
adView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getHeightAd(), MeasureSpec.EXACTLY));
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
adView.layout(l, 0, r, getHeightAd());
myView.layout(drawRect.left, drawRect.top, drawRect.right, drawRect.bottom);
}
#Override public boolean onTouchEvent(MotionEvent event) {
drawRect.offsetTo((int)event.getX()-drawRect.width()/2, (int)event.getY()-drawRect.height()/2);
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
addView(myView);
break;
case MotionEvent.ACTION_MOVE:
requestLayout();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
removeView(myView);
default:
break;
}
return true;
}
private class Test1 extends View {
Path path = new Path();
Bitmap bitmap;
public Test1(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.anImage);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.moveTo(0, 0);
path.lineTo(getWidth(), 0);
path.lineTo(getWidth()/2, getHeight());
path.moveTo(0, 0);
canvas.clipPath(path);
canvas.drawBitmap(bitmap, 0, 0, null); }
}
}
The distorted view when showing ads:
and when not, as it should be:
Finally I found a solution. Based on this post, I modified the code like this (added the setLayer line):
...
}
private class Test1 extends View {
Path path = new Path();
Bitmap bitmap;
public Test1(Context context) {
super(context);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable. anImage);
}
...

Android Vertical Seek Bar like Google Play Music App

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.

Vertical SeekBar behaves strangely when initiated on a thread

I'm using a simple Vertical SeekBar that is working fine if I initiate it on the onCreate function. But if I initiate the SeekBar on a different thread the thumb position does not work as expected.
The code I'm using to initiate the SeekBar:
public class MainActivity extends Activity {
AbsoluteLayout mainLayout;
VerticalSeekBar seekBar;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=this;
mainLayout=(AbsoluteLayout)findViewById(R.id.main_layout_id);
Thread thread1 =new Thread(runnable1);
thread1.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private Runnable runnable1 = new Runnable(){
#Override
public void run() {
seekBar=new VerticalSeekBar(context);
loadMainScreen.sendEmptyMessage(0);
}
};
Handler loadMainScreen = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
AbsoluteLayout.LayoutParams parameters = new AbsoluteLayout.LayoutParams(40,200,150,30);
mainLayout.addView(seekBar,parameters);
}
};
}
I do not think the problem is on the SeekBar but I will show the code anyway.
public class VerticalSeekBar extends SeekBar implements OnSeekBarChangeListener {
public VerticalSeekBar(Context context) {
super(context);
this.setOnSeekBarChangeListener(this);
}
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;
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
I try changing the Context I'm passing to the variable context to getApplicationContext() and getBaseContext() but it did not work.
If I put the initialization on a runOnUiThread it crashes because the SeekBar is not initialized when I try to add to the layout. If I put both the initialization and the addView on a runOnUiThread it works but that is not what I want.
I was wondering if there is something I could do regarding the Context to make it work. Any different ideas are welcome.
Thanks in advance

Android Seekbar - only allow change with thumb?

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

Categories

Resources