I have made a demo project for image rotation in seekbar progresschange. I have successfully done it on button change but its not working on seekbar change. Here is what I tried:
xml
<ImageView
android:id="#+id/iv_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/enr" />
<SeekBar
android:id="#+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:max="360"
android:padding="1dp"
android:progress="0" />
<Button
android:id="#+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/seekbar"
android:layout_centerHorizontal="true"
android:text="Rotate" />
code
public class MainActivity extends Activity implements OnSeekBarChangeListener {
ImageView iv_image;
SeekBar seekbar;
Bitmap source;
float angle = 0;
Button buttonClick;
Bitmap rotatedImage;
static Matrix matrix;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
buttonClick = (Button) findViewById(R.id.bt);
buttonClick.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
angle += 90;
iv_image.buildDrawingCache();
source = iv_image.getDrawingCache();
rotatedImage = rotateImage(source, angle);
iv_image.setImageBitmap(rotatedImage);
}
});
}
void init() {
iv_image = (ImageView) findViewById(R.id.iv_image);
seekbar = (SeekBar) findViewById(R.id.seekbar);
seekbar.setOnSeekBarChangeListener(this);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
angle = progress;
iv_image.buildDrawingCache();
source = iv_image.getDrawingCache();
rotatedImage = rotateImage(source, angle);
iv_image.setImageBitmap(null);
iv_image.setImageBitmap(rotatedImage);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public static Bitmap rotateImage(Bitmap sourceImage, float angle) {
matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(sourceImage, 0, 0, sourceImage.getWidth(),
sourceImage.getHeight(), matrix, true);
}
}
You forgot to attach OnSeekBarChangeListener to your SeekBar:
void init() {
iv_image = (ImageView) findViewById(R.id.iv_image);
seekbar = (SeekBar) findViewById(R.id.seekbar);
seekbar.setOnSeekBarChangeListener(this); // <-----
}
I suggest you use the Picasso library by Square. It will be much simpler and straightforward for this need here
Related
How it looks
I want to check intersection between ImageView to ImageView2 as LinearLayout slides towards ImageView2.
I used Rect but it is not working, ImageView2 Just passed throught it without getting intersect.
Please help me!!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<ImageView
android:id="#+id/tile"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/tile" />
<LinearLayout
android:id="#+id/l1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageView
android:id="#+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
<ImageView
android:id="#+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
</LinearLayout>
#SuppressLint("NewApi")
public class MainActivity extends Activity {
Rect tileRect = new Rect();
Rect b1Rect = new Rect();
Rect b2Rect = new Rect();
ImageView tile,b1,b2;
RelativeLayout layout;
LinearLayout l1;
final Handler h = new Handler();
Boolean tileRight=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
move();
}
private void init() {
// TODO Auto-generated method stub
b1 = (ImageView)findViewById(R.id.b1);
b2 = (ImageView)findViewById(R.id.b2);
tile = (ImageView)findViewById(R.id.tile);
layout = (RelativeLayout)findViewById(R.id.layout);
l1 = (LinearLayout)findViewById(R.id.l1);
tile.setX(320);
tile.setY(800);
l1.setVisibility(View.VISIBLE);
}
public void move()
{
final int delay = 45;
h.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(tileRight==true)
tileRight=false;
else
tileRight=true;
return true;
}
return false;
}
});
if(tileRight==true)
{
if(tile.getX()>600f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()+speedTile);
}
}
else{
if(tile.getX()<40f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()-speedTile);
}
}
tile.getHitRect(tileRect);
b1.getHitRect(b1Rect);
b2.getHitRect(b2Rect);
if(Rect.intersects(tileRect, b1Rect) || Rect.intersects(tileRect, b2Rect))
{
gameOver();
}
l1.setY(l1.getY()+10f);
h.postDelayed(this, delay);
}
},delay);
}
private void gameOver() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android's View has getLocationOnScreen() method that shows absolute position of your view.
https://developer.android.com/reference/android/view/View.html#getLocationOnScreen(int[])
The issue occurs because view.getHitRect() is used before the layouts are inflated.
Any of the view's position or measurement APIs like getWidth(), getTop(), getRight() etc. will return 0 (getHitRect() initializes the Rect with (0,0,0,0)) in onCreate() or onResume() before the views are inflated.
In your case, it appears that the Handler's delay period executes the intersection logic earlier than view inflation.
You could post from the view and the run() method will execute after the view inflates and then obtain the view's measurement parameters or a Rect .
Here is an example:
public class MyTestActivity extends AppCompatActivity{
int mNumberOfViewsInitialized = 0;
ImageView mImageViewRight, mImageViewLeft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_image_activity);
mImageViewLeft = (ImageView) findViewById(R.id.image_view_left);
mImageViewRight = (ImageView) findViewById(R.id.image_view_right);
// calling method here will log that the views do not intersect
// which happens because they haven't been inflated yet.
// doViewsOverlap();
mImageViewLeft.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
mImageViewRight.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
}
private void intersectionLogic(){
/* the constant could be something else, depending
on the number of views you'd like to test intersection for*/
if(mNumberOfViewsInitialized == 2){
doViewsOverlap(mImageViewLeft,mImageViewRight);
}
}
private void doViewsOverlap(final View firstView, final View secondView){
Rect leftRect = new Rect();
firstView.getHitRect(leftRect);
Rect rightRect = new Rect();
secondView.getHitRect(rightRect);
if(Rect.intersects(leftRect,rightRect) || Rect.intersects(rightRect,leftRect))
Log.v("intersects","views intersect");
else
Log.v("intersects","views do not intersect");
}
}
I used a layout which does not animate / move the images, but the same issue should occur when the images are moved as well
<ImageView
android:id="#+id/image_view_left"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:background="#android:color/holo_blue_dark"
android:src = "#mipmap/ic_launcher"/>
<ImageView
android:id="#+id/image_view_right"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentRight="true"
android:background="#android:color/holo_green_dark"
android:gravity="end"
android:src="#mipmap/ic_launcher"/>
Images contained in a RelativeLayout.
Here is a screenshot of the UI:
This problem is related to this: If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Hope this helps.
Filters.java
public class Filters extends Activity implements OnSeekBarChangeListener{
private SeekBar PRICEbar,DISTANCEbar, RATINGbar; // declare seekbar object variable
// declare text label objects
private TextView PRICEtextProgress,DISTANCEtextProgress, RATINGtextProgress;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// load the layout
setContentView(R.layout.filters);
PRICEbar = (SeekBar)findViewById(R.id.PRICEseekBarID); // make seekbar object
PRICEbar.setOnSeekBarChangeListener(this);
PRICEbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
PRICEtextProgress = (TextView)findViewById(R.id.PRICEtextViewProgressID);
PRICEtextProgress.setText("Price:: Rs "+progress);
}
});
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (seekBar == PRICEbar)
PRICEtextProgress.setText("Price:: Rs "+progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
filters.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/relativeLayoutforPRICE"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/PRICEtextViewProgressID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Price"
android:textAppearance="?android:attr/textAppearanceLarge" >
</TextView>
<SeekBar
android:id="#+id/PRICEseekBarID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:layout_marginTop="26dp"
android:max="100" >
</SeekBar>
</RelativeLayout>
</LinearLayout>
I have an output like this::
How to modify my code to get initial and final values in the seek bar as in figure below?
You have already defined max value of seekbar
android:max="100"
Now you need to add two textviews on left and right of seekbar. Use Relative layout and align both textviews Left and Right to the parent.
Brontok's hint solved my problem. I just had to alter the XML. I want to share the result here:
<RelativeLayout
android:id="#+id/relativeLayoutforPRICE"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/PRICEtextViewProgressID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Price"
android:textAppearance="?android:attr/textAppearanceLarge" >
</TextView>
<SeekBar
android:id="#+id/PRICEseekBarID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:layout_marginTop="26dp"
android:max="100" >
</SeekBar>
<TextView
android:id="#+id/PRICEinitialvaluetextID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PRICEseekBarID"
android:text="Rs 0" >
</TextView>
<TextView
android:id="#+id/PRICEinitialvaluetextID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/PRICEseekBarID"
android:text="Rs 100" />
</RelativeLayout>
First, I think you should extend SeekBar.
Second, call canvas.drawText() in onDraw() method to draw text before SeekBar and after SeekBar.
This way you can refresh the textView in your onDraw method callback
check it out, You implemented OnSeekBarChangeListener created methods, and set
public class Filters extends Activity implements OnSeekBarChangeListener{
PRICEbar.setOnSeekBarChangeListener(this);
and next line you override it with new OnSeekBarChangeListener
PRICEbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
you can delete implements OnSeekBarChangeListener and these 3 empty methods from your activity (onSeekBarChange, onStartTracking, onStopTracking)
just for fun with an empty linear layout in main.xml
a sample with seekbar
import android.app.*;
import android.os.*;
import android.view.*;
import android.content.*;
import android.graphics.*;
import android.graphics.Color.*;
import android.graphics.drawable.*;
import android.graphics.drawable.shapes.*;
import android.widget.*;
import android.widget.ProgressBar;
import android.text.*;
//import org.apache.http.impl.conn.*;
import android.util.*;
import android.view.View.*;
import android.widget.SeekBar.*;
public class MainActivity extends Activity {
public int angle=30;
#Override
//CustomDrawableView customDrawableView;
LinearLayout myLayout;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myLayout = findViewById(R.id.linear_layout);
//setContentView(customDrawableView);
/* TextView text1 = new TextView(this);
text1.setText(R.string.hello_world);
myLayout.addView(text1);
*/
final TextView text2 = new TextView(this);
text2.setText("30");
myLayout.addView(text2);
SeekBar seek = new SeekBar(this);
//seek.setMin(2);
seek.setMax(180);
seek.setProgress(30);
myLayout.addView(seek);
final CustomDrawableView customDrawableView = new CustomDrawableView(this);
myLayout.addView(customDrawableView);
customDrawableView.setBackgroundColor(0x00888888);
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
public void onProgressChanged(SeekBar seek,int value,boolean usr){
angle = value;
if (angle<=2) angle = 2;
text2.setText(String.valueOf(value));
customDrawableView.invalidate();
}
public void onStartTrackingTouch(SeekBar seek){
}
public void onStopTrackingTouch(SeekBar seek){
}
});
//customDrawableView.setRotationX(45);
}; // MainActivity_onCreate
public class CustomDrawableView extends View {
private int n=16;
private ShapeDrawable[] drws = new ShapeDrawable[4*n];
protected Canvas canvas;
public CustomDrawableView(Context context) {
super(context);
setContentDescription(context.getResources().getString(
R.string.my_view_desc));
angle = 30;
};
protected void onDraw(Canvas oCanvas) {
canvas = oCanvas;
show();
}; // onDraw
public void show() {
int cx = canvas.getWidth()/2;
int cy = canvas.getHeight()/2;
int color = Color.argb(0x88,0x00,0x99,0xff);
int stp;
for (int s=0;s<180;s+=angle){
canvas.rotate(angle,cx,cy);
for (int i=0;i<=15;i++){
stp = 29 - i;
color = Color.argb(i*10, i*17, 0xaa, 0xff - i*10);
drws[i] = new ShapeDrawable(new OvalShape());
drws[i].getPaint().setColor(color);
drws[i].setBounds(cx+stp*i, cy+10, cx+30+stp*i, cy+20);
drws[n+i] = new ShapeDrawable(new OvalShape());
drws[n+i].getPaint().setColor(color);
drws[n+i].setBounds(cx+10+stp*i, cy, cx+20+stp*i, cy+30);
drws[2*n+i] = new ShapeDrawable(new OvalShape());
drws[2*n+i].getPaint().setColor(color);
drws[2*n+i].setBounds(cx-stp*i-30, cy-20, cx-stp*i, cy-10);
drws[3*n+i] = new ShapeDrawable(new OvalShape());
drws[3*n+i].getPaint().setColor(color);
drws[3*n+i].setBounds(cx-stp*i-20, cy-30, cx-stp*i-10, cy);
canvas.rotate(22.5f,cx,cy);
drws[i].draw(canvas);
drws[n+i].draw(canvas);
drws[2*n+i].draw(canvas);
drws[3*n+i].draw(canvas);
}
canvas.rotate(angle,cx,cy);
}
}
}; // CustomDrawableView
}; // MainActivity
Following the instructions here: How to make custom seek bar in android? I was able to make my own custom seekbar that draws text inside the thumb. I know want to create my own seekbar class so that I can call it from my activity. I'm running into problems because when I create a seekbar in my main activity it does not work properly. I don't think I have set up the OnSeek Listener correctly. Here is my main class:
public class MainActivity extends Activity {
CustomSeekBar test;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
test = (CustomSeekBar) findViewById(R.id.seekBar1);
setContentView(R.layout.activity_main);
}
}
Here is my CustomSeekBar class:
public class CustomSeekBar extends SeekBar implements OnSeekBarChangeListener {
String TAG = "TOUCHING";
SeekBar seekbar;
public CustomSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int value = seekBar.getProgress();
String valueString = value + "";
seekBar.setThumb(writeOnDrawable(R.drawable.thumbler_small, valueString));
Log.d(TAG, "Thumb is being touched");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public BitmapDrawable writeOnDrawable(int drawableId, String text) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId)
.copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(20);
Canvas canvas = new Canvas(bm);
canvas.drawText(text, 0, bm.getHeight() / 2, paint);
return new BitmapDrawable(bm);
}
}
Here is my activity_main.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SeekBar
android:name="com.example.customseekbarclass"
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:indeterminate="false"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:progressDrawable="#drawable/styled_progress"
android:thumb="#drawable/thumbler_small" />
</RelativeLayout>
This is the way my directory is setup:
How do I setup the SeekBar in my main activity class so that it calls the methods from my SeekBar class?
you should switch
test = (CustomSeekBar) findViewById(R.id.seekBar1);
setContentView(R.layout.activity_main);
since R.id.seekBar1 belongs to activity_main.xml otherwise you will get null for test:
setContentView(R.layout.activity_main);
test = (CustomSeekBar) findViewById(R.id.seekBar1);
Then I would change the seekbar part of your layout this way
<com.example.CustomSeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:indeterminate="false"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:progressDrawable="#drawable/styled_progress"
android:thumb="#drawable/thumbler_small" />
I solved this by calling the OnSeekBarChangeListener from my main activity class:
public class MainActivity extends Activity {
CustomSeekBar test;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
test = (CustomSeekBar) findViewById(R.id.seekBar1);
test.setOnSeekBarChangeListener(test);
}
}
and adding the missing constructors from my CustomSeekBar class:
public class CustomSeekBar extends SeekBar implements OnSeekBarChangeListener {
String TAG = "TOUCHING";
SeekBar mSeekBar;
public CustomSeekBar(Context context) {
super(context);
}
public CustomSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
int value = seekBar.getProgress();
String valueString = value + "";
seekBar.setThumb(writeOnDrawable(R.drawable.thumbler_small, valueString));
Log.d(TAG, "Thumb is being touched");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.d(TAG, "START");
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.d(TAG, "STOP");
}
public BitmapDrawable writeOnDrawable(int drawableId, String text) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId)
.copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(20);
Canvas canvas = new Canvas(bm);
canvas.drawText(text, 0, bm.getHeight() / 2, paint);
return new BitmapDrawable(bm);
}
}
there is a layout, where I have some buttons, controls and an imageView. When the layout shows up, everything is okay. But later, when the requested image (the image of the aveform) is downloaded and I try to set it to the ImageView with setImageBitmap. The whole layout become messed up. Here are some pics.
This is how the layout looks like, when image has not been downloaded:
This is after the setImageBitMap
Here is my xml (I use a custom subclass of imageView, but the error also occurs withz the original mageView)
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
>
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<adam.czibere.WaveFormSurfaceView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</TableRow>
<TableRow
android:id="#+id/tableRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="20dp"
android:layout_gravity="center"
android:thumb="#drawable/progress_fill" />
</TableRow>
<TableRow
android:id="#+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/currentPos"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="right"
android:layout_weight="5"
android:text="00:00.000" />
<TextView
android:id="#+id/textView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_weight="1"
android:text="/" />
<TextView
android:id="#+id/endPos"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:gravity="left"
android:text="00:00.000" />
</TableRow>
<TableRow
android:id="#+id/tableRow4"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="#+id/closebtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Close" />
<Button
android:id="#+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Play" />
<ToggleButton
android:id="#+id/toggleButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="ToggleButton" />
</TableRow>
</TableLayout>
Here is the extended imageView:
public class WaveFormSurfaceView extends ImageView {
public boolean isEditMode = false;
Bitmap waveform = null;
int touchCount = 0;
List<VerbaComment> myComments = new ArrayList<VerbaComment>();
int lastTouch_x = -1;
public WaveFormSurfaceView(Context context) {
super(context);
}
public WaveFormSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WaveFormSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// copies the given waveform to a variable
public void setWaveForm(Bitmap b) {
waveform = Bitmap.createBitmap(b.getWidth(), b.getHeight(),
b.getConfig());
// copy the pixel to it
int[] allpixels = new int[b.getHeight() * b.getWidth()];
b.getPixels(allpixels, 0, b.getWidth(), 0, 0, b.getWidth(),
b.getHeight());
waveform.setPixels(allpixels, 0, b.getWidth(), 0, 0, b.getWidth(),
b.getHeight());
}
#Override
public void setImageBitmap(Bitmap bm) {
// TODO Auto-generated method stub
super.setImageBitmap(bm);
setWaveForm(bm);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// System.out.println("waveform width: "+waveform.getWidth());
// setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
// setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
// setMeasuredDimension(1000,200);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
// super.onDraw(canvas);
// Create a paint object for us to draw with, and set our drawing color
// to blue.
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAlpha(50);
Paint paint1 = new Paint();
paint1.setColor(Color.GREEN);
paint1.setAlpha(50);
// draws the rectangle
if (waveform != null) {
canvas.drawBitmap(waveform, 0, 0, null);
if (isEditMode) {
for (VerbaComment vc : myComments) {
System.out.println("drawing the comment... start: "
+ vc.start + " end: " + vc.end);
canvas.drawRect(vc.start, canvas.getHeight(), vc.end, 0,
paint);
}
}
System.out.println("waveform width, height:" + waveform.getWidth()
+ " x " + waveform.getHeight());
} else {
canvas.drawRect(0, 0, 50, 50, paint);
}
// mImageView.setImageBitmap(map);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_UP) {
if (isEditMode) {
touchCount++;
// lastTouch_x=(int)event.getX();
// System.out.println("onTouch; touchCount: "+touchCount+" lasttouch_x: "+lastTouch_x);
if (touchCount % 2 == 0) {
VerbaComment temp = new VerbaComment(lastTouch_x,
(int) event.getX());
myComments.add(temp);
} else {
lastTouch_x = (int) event.getX();
System.out.println("onTouch; touchCount: " + touchCount
+ " lasttouch_x: " + lastTouch_x);
}
}
}
invalidate();
return true;
}
}
And here is the activity:
public class AudioPlayerActivity extends Activity{
// Hardcoded parameters for the Verba demo server
private static final String ServerURL = "http://demo.verba.com";
private static final String MediaPath = "C:\\Program%20Files\\Verba\\media\\";
// Player user interface elements
private Button mBtnPlay;
private WaveFormSurfaceView mImageView;
//private ImageView mImageView;
private SeekBar mSeekBar;
private TextView mCurrentPos;
private TextView mEndPos;
private Bitmap originalWaveForm;
// THIS IS THE MEDIAPLAYER (has no UI, only loads and plays the audio)
private MediaPlayer mMediaPlayer;
// HTTP URL for the audio waveform PNG picture
private String getWaveformURL(String pCallURL) {
return ServerURL + ":8089/a?" + MediaPath + pCallURL
+ "?10000200240240240123023048240240240240240240";
}
// HTTP URL for the audio transcoded to MP3 format
private String getMediaURL(String pCallURL) {
return ServerURL + ":10100/getMedia?file=" + MediaPath + pCallURL
+ "&format=mp3";
}
// Downloads the waveform image outside of the main GU thread
private class DownloadWaveformTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... urls) {
try {
return BitmapFactory.decodeStream((InputStream) new URL(
getWaveformURL(myCallURL))
.getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
try {
Thread.sleep(50000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mImageView.setImageBitmap(result);
}
}
// Updates the seekbar outside of the main GU thread, started only after
// MediaPlayer exists
private class SeekBarUpdater extends Thread {
float p=0;
#Override
public void run() {
final SimpleDateFormat tf = new SimpleDateFormat("mm:ss.SSS");
final Calendar calendar = Calendar.getInstance();
int currentPosition = 0;
final int total = mMediaPlayer.getDuration(); // //returns in msec,
// final because we
// will use in the
// runnable
// UI update must happen on the UI thread, so we post our actions
// there in a runnable
mCurrentPos.post(new Runnable() {
public void run() {
calendar.setTimeInMillis(total);
mEndPos.setText(tf.format(calendar.getTime()));
mSeekBar.setMax(total);
}
});
while (mMediaPlayer != null && currentPosition < total) {
try {
Thread.sleep(50);
currentPosition = mMediaPlayer.getCurrentPosition(); // returns
// in
// msec
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
// we are roughly adjusting for delays due to the thread
// communication
// currentPosition -= 100;
// if (currentPosition < 0 ) currentPosition = 0;
final int currPosition = currentPosition; // final because we
// will use in the
// runnable
p=(float)currentPosition/(float)total;
// UI update must happen on the UI thread, so we post our
// actions there in a runnable
mCurrentPos.post(new Runnable() {
public void run() {
calendar.setTimeInMillis(currPosition);
mCurrentPos.setText(tf.format(calendar.getTime()));
mSeekBar.setProgress(currPosition);
System.out.println("pecent="+p);
drawRectOnWaveForm(p);
}
});
}
}
}
String myCallURL;
/**
* Create a new instance of MyFragment that will be initialized
* with the given arguments.
*/
static MediaPlayerFragment newInstance(CharSequence url) {
MediaPlayerFragment f = new MediaPlayerFragment();
Bundle args = new Bundle();
args.putCharSequence("call_url", url);
f.setArguments(args);
return f;
}
/**
* During creation, if arguments have been supplied to the fragment
* then parse those out.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value1 = extras.getString("call_url");
if(value1!=null){
myCallURL=value1;
}
}
DownloadWaveformTask task = new DownloadWaveformTask();
task.execute();
setContentView(R.layout.mediaplayer);
System.out.println("AudioPlayerActivity setContentView, mycallurl: "+myCallURL);
// part of the player UI
//mImageView = (ImageView) findViewById(R.id.imageView);
mImageView = (WaveFormSurfaceView) findViewById(R.id.imageView);
mBtnPlay = (Button) findViewById(R.id.playButton);
mSeekBar = (SeekBar) findViewById(R.id.seekBar);
mCurrentPos = (TextView) findViewById(R.id.currentPos);
mEndPos = (TextView) findViewById(R.id.endPos);
ToggleButton tb=(ToggleButton) findViewById(R.id.toggleButton1);
tb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked){
mImageView.isEditMode=true;
mImageView.invalidate();
}else{
mImageView.isEditMode=false;
mImageView.invalidate();
}
}
});
//
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
// we only update the player if the change comes from a user
// action
mMediaPlayer.seekTo(progress);
}
}
});
// IMPORTANT
// - The DownloadWaveformTask part should go into the initialization of
// the player fragment
// - currently we are NOT handling currently the end of playback
// situations, we should
// - currently we are NOT releasing the MediaPlayer resource, we should
// when a fragment closes
mBtnPlay.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
mBtnPlay.setText("Play");
} else {
mMediaPlayer.start();
mBtnPlay.setText("Pause");
}
} else {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
// this updates the seekbar as the buffering happens
mMediaPlayer
.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mp,
int percent) {
// TODO Auto-generated method stub
mSeekBar.setSecondaryProgress((int) (mSeekBar
.getMax() * percent / 100));
}
});
try {
final String lMediaURL = getMediaURL(myCallURL);
mMediaPlayer.setDataSource(lMediaURL);
mMediaPlayer.prepare(); // might take long! (for
// buffering, etc)
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mMediaPlayer.start();
mBtnPlay.setText("Pause");
// we start the thread that updates the seekbar, based on
// the state of the player
SeekBarUpdater thread = new SeekBarUpdater();
thread.start();
}
}
});
// Close button
Button closeBtn = (Button) findViewById(R.id.closebtn);
closeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//TODO ha megy a lejátszás, megállítjuk
if(mMediaPlayer!=null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
}
finish();
}
});
}
}
Okz here are some flaws i have got in your code
You are giving android:layout_gravity="center" to your SeekBar and on other hand you are giving it match_parent attribute
Why you are giving fill_parent to your id/tableRow3
and try to use fill_parent instead of match _parent because fill_parent is backword compatible
I want to create one button/layout object dynamically from the object that exist on the current layout and want to handle both differently..
Here is my code that I implemented..
declared globally
Button btnStart, btnButton1, btnButton2, btnButton3;
and in OnCreate()
btnStart = (Button) findViewById(R.id.btnStart);
btnButton1 = (Button) findViewById(R.id.Button1);
btnButton2 = (Button) findViewById(R.id.Button2);
btnButton3 = btnButton1; // Problem comes here.
I want to create btnButton3 dynamically same as btnButton1. On clicking the
btnStart I am running animations for btnButton1, btnButton2 and btnButton3.
Now the issue is btnButton2 running animation fine.. but btnButton1 is not animating
and instead btnButton3 is animating.
Here's my complete code..
public class TweenAnimationActivity extends Activity {
/** Called when the activity is first created. */
Button btnStart, btnButton1, btnButton2, btnButton3;
FrameLayout mainLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout = (FrameLayout) findViewById(R.id.flMain);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Log.e("Dimension", "Width : " + width + " Height : " + height);
btnStart = (Button) findViewById(R.id.btnStart);
btnButton1 = (Button) findViewById(R.id.Button1);
btnButton2 = (Button) findViewById(R.id.Button2);
btnButton3 = btnButton1;
// btnButton3.setLayoutParams(relativeParams);
final Animation animation = new TranslateAnimation(0, 0, 0,
height - 220);
animation.setDuration(5000);
animation.setFillAfter(true);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
btnButton1.setText("Moving");
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
btnButton1.setText("Moved");
}
});
final Animation animation1 = new TranslateAnimation(0, 0, 0,
-(height - 220));
// animation1.setStartOffset(1000);
animation1.setDuration(5000);
animation1.setFillAfter(true);
animation1.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
btnButton2.setText("Moving");
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
btnButton2.setText("Moved");
}
});
// final Animation animation2 = new TranslateAnimation(0, 0, -(width - 220),
// height - 220);
final Animation animation2 = new TranslateAnimation(0, 0, (width - 220),
height - 220);
animation2.setDuration(5000);
animation2.setFillAfter(true);
animation2.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
btnButton3.setText("MovingCopied");
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
btnButton3.setText("MovedCopied");
}
});
btnStart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
btnButton1.startAnimation(animation);
btnButton2.startAnimation(animation1);
btnButton3.startAnimation(animation2);
}
});
}
}
any here's my layout..
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flMain"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<Button
android:id="#+id/Button1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="top|right"
android:text="Button1" />
<Button
android:id="#+id/Button2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="bottom|right"
android:text="Button2" />
</FrameLayout>
In your code, btnButton3 = btnButton1, you have not created button3 object just created a reference of button1.
try
btnButton3 = new Button(this)
btnButton3.setLayoutParams(btnButton1.getLayoutParams());
mainLayout.addView(btnButton3);
and for better tutorial you can look here.