I want my game to exit and go to a separate Activity when the user collides. For example, I want it to go back to my main menu. I've tried adding a Button, new intent method etc and these don't work. I can't find the answer anywhere and i'm not knowledgeable enough to do this as I'm learning. I've trawled the internet but nothing has really helped. Any advice would be awesome. My idea was to change the newgame() method to exit the game?
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
import java.util.Random;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private Threading threading;
private BackgroundImage bg;
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
public static final int MovementSpeed = -8;
private Player player;
private ArrayList<BorderTop> borderTop;
private ArrayList<BorderBottom> borderBottom;
private ArrayList<Smokepuff> smoke;
private ArrayList<Missile> missiles;
private int MaximumBorderHeight;
private int MinimumBorderHeight;
private boolean topDown = true;
private boolean botDown = true;
private int progressDifficulty = 20;
private Random rand = new Random();
private boolean newGameCreated;
private long smokeStartTime;
private long missileStartTime;
public GamePanel(Context context) {
super(context);
getHolder().addCallback(this);
setFocusable(true);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
bg = new BackgroundImage(BitmapFactory.decodeResource(getResources(), R.drawable.grassbg1));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.smallcatfinal), 40, 44, 1);
borderTop = new ArrayList<BorderTop>();
borderBottom = new ArrayList<BorderBottom>();
smoke = new ArrayList<Smokepuff>();
missiles = new ArrayList<Missile>();
smokeStartTime= System.nanoTime();
missileStartTime = System.nanoTime();
threading = new Threading(getHolder(), this);
threading.setRunning(true);
threading.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
int counter = 0;
while (retry && counter < 1000) {
counter++;
try {
threading.setRunning(false);
threading.join();
retry = false;
threading = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (!player.getPlaying()) {
player.setPlaying(true);
player.setUp(true);
}else{
player.setUp(true);
}
return true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
player.setUp(false);
return true;
}
return super.onTouchEvent(event);
}
public void update() {
if (player.getPlaying()) {
bg.update();
player.update();
MaximumBorderHeight = 30 + player.getScore() / progressDifficulty;
if (MaximumBorderHeight > HEIGHT / 4) MaximumBorderHeight = HEIGHT / 4;
MinimumBorderHeight = 5 + player.getScore() / progressDifficulty;
//check bottom border collision
for (int i = 0; i < borderBottom.size(); i++) {
if (collision(borderBottom.get(i), player))
player.setPlaying(false);
}
//check top border collision
for (int i = 0; i < borderTop.size(); i++) {
if (collision(borderTop.get(i), player))
player.setPlaying(false);
}
this.updateTop();
this.updateBottom();
long missileElapsed = (System.nanoTime() - missileStartTime) / 1000000;
if (missileElapsed > (2000 - player.getScore() / 4)) {
//first missile always goes down the middle
if (missiles.size() == 0) {
missiles.add(new Missile(BitmapFactory.decodeResource(getResources(), R.drawable.
missile), WIDTH + 10, HEIGHT / 2, 45, 15, player.getScore(), 13));
} else {
missiles.add(new Missile(BitmapFactory.decodeResource(getResources(), R.drawable.missile),
WIDTH + 10, (int) (rand.nextDouble() * (HEIGHT - (MaximumBorderHeight * 2)) + MaximumBorderHeight), 45, 15, player.getScore(), 13));
}
//reset timer
missileStartTime = System.nanoTime();
}
//loop through every missile and check collision and remove
for (int i = 0; i < missiles.size(); i++) {
//update missile
missiles.get(i).update();
if (collision(missiles.get(i), player)) {
missiles.remove(i);
player.setPlaying(false);
break;
}
//remove missile if it is way off the screen
if (missiles.get(i).getX() < -100) {
missiles.remove(i);
break;
}
}
long elapsed = (System.nanoTime() - smokeStartTime) / 1000000;
if (elapsed > 120) {
smoke.add(new Smokepuff(player.getX(), player.getY() + 10));
smokeStartTime = System.nanoTime();
}
for (int i = 0; i < smoke.size(); i++) {
smoke.get(i).update();
if (smoke.get(i).getX() < -10) {
smoke.remove(i);
}
}
} else {
newGameCreated = false;
if (!newGameCreated) {
newGame();
}
}
public boolean collision (GameObject a, GameObject b)
{
if (Rect.intersects(a.getRectangle(), b.getRectangle())) {
return true;
}
return false;
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
final float ScaleX = (float) getWidth() / WIDTH*1.f;
final float ScaleY = (float) getHeight() / HEIGHT*1.f;
if (canvas != null) {
final int savedState = canvas.save();
canvas.scale(ScaleX, ScaleY);
bg.draw(canvas);
player.draw(canvas);
for(Smokepuff sp: smoke)
{
sp.draw(canvas);
}
//draw missiles
for(Missile m: missiles)
{
m.draw(canvas);
}
for(BorderTop bt: borderTop)
{
bt.draw(canvas);
}
for(BorderBottom bb: borderBottom)
{
bb.draw(canvas);
}
canvas.restoreToCount(savedState);
}
}
public void updateBottom() {
if (player.getScore() % 40 == 0) {
borderBottom.add(new BorderBottom(BitmapFactory.decodeResource(getResources(), R.drawable.brick),
borderBottom.get(borderBottom.size() - 1).getX() + 20, (int) ((rand.nextDouble()
* MaximumBorderHeight) + (HEIGHT - MaximumBorderHeight))));
}
//update bottom border
for (int i = 0; i < borderBottom.size(); i++) {
borderBottom.get(i).update();
//if border is moving off screen, remove it and add a corresponding new one
if (borderBottom.get(i).getX() < -20) {
borderBottom.remove(i);
//determine if border will be moving up or down
if (borderBottom.get(borderBottom.size() - 1).getY() <= HEIGHT - MaximumBorderHeight) {
botDown = true;
}
if (borderBottom.get(borderBottom.size() - 1).getY() >= HEIGHT - MinimumBorderHeight) {
botDown = false;
}
if (botDown) {
borderBottom.add(new BorderBottom(BitmapFactory.decodeResource(getResources(),R.drawable.brick
), borderBottom.get(borderBottom.size() - 1).getX() + 20, borderBottom.get(borderBottom.size() - 1
).getY() + 1));
} else {
borderBottom.add(new BorderBottom(BitmapFactory.decodeResource(getResources(), R.drawable.brick
), borderBottom.get(borderBottom.size() - 1).getX() + 20, borderBottom.get(borderBottom.size() - 1
).getY() - 1));
}
}
}
}
public void updateTop()
{
if (player.getScore() % 50 == 0) {
borderTop.add(new BorderTop(BitmapFactory.decodeResource(getResources(), R.drawable.brick), borderTop.get(borderTop.size() - 1).getX() + 20, 0, (int) ((rand.nextDouble() * (MaximumBorderHeight)) + 1)));
}
for (int i = 0; i < borderTop.size(); i++) {
borderTop.get(i).update();
if (borderTop.get(i).getX() < -20) {
borderTop.remove(i);
if (borderTop.get(borderTop.size() - 1).getHeight() >= MaximumBorderHeight) {
topDown = false;
}
if (borderTop.get(borderTop.size() - 1).getHeight() <= MinimumBorderHeight) {
topDown = true;
}
if (topDown) {
borderTop.add(new BorderTop(BitmapFactory.decodeResource(getResources(), R.drawable.brick), borderTop.get(borderTop.size() - 1).getX() + 20, 0, borderTop.get(borderTop.size() - 1).getHeight() + 1));
} else {
borderTop.add(new BorderTop(BitmapFactory.decodeResource(getResources(), R.drawable.brick), borderTop.get(borderTop.size() - 1).getX() + 20, 0, borderTop.get(borderTop.size() - 1).getHeight() - 1));
}
}
}
}
public void newGame() {
borderBottom.clear();
borderTop.clear();
missiles.clear();
smoke.clear();
MinimumBorderHeight = 5;
MaximumBorderHeight = 30;
player.resetDY();
player.resetScore();
player.setY(HEIGHT/2);
//create initial borders
//initial top border
for(int i = 0; i*20<WIDTH+40;i++)
{
// first top border create
if(i==0)
{borderTop.add(new BorderTop(BitmapFactory.decodeResource(getResources(),R.drawable.brick
),i*20,0, 10));
}
else
{
borderTop.add(new BorderTop(BitmapFactory.decodeResource(getResources(),R.drawable.brick
),i*20,0, borderTop.get(i-1).getHeight()+1));
}
}
//initial bottom border
for(int i = 0; i*20<WIDTH+40; i++)
{
//first border ever created
if(i==0)
{
borderBottom.add(new BorderBottom(BitmapFactory.decodeResource(getResources(),R.drawable.brick)
,i*20,HEIGHT - MinimumBorderHeight));
}
//adding borders until the initial screen is filed
else
{
borderBottom.add(new BorderBottom(BitmapFactory.decodeResource(getResources(), R.drawable.brick),
i * 20, borderBottom.get(i - 1).getY() - 1));
}
}
newGameCreated = true;
}
}
Related
How can I get started filling up text similar to this screen? Should I use a Handler and delay every character?
The background is that I am coding a mini game for Android similar to the classic Moon Patrol and now I want to create bonus for completing a checkpoint.
You can find my beta in the appstore https://play.google.com/store/apps/details?id=dev.android.buggy It is currently named "Moon Buggy". The code is available on request, right now the repo is closed source.
I put a test checkpoint at checkpoint "C" to show what I try:
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class ParallaxView extends SurfaceView implements Runnable, SurfaceHolder.Callback {
int bombed = 5;
boolean waitForTimer = false;
boolean waitForTimer2 = false;
boolean recent = true;
char checkpoint;
boolean checkp = true;
Rect fromRect1;
Rect toRect1;
Rect fromRect2;
Rect toRect2;
boolean incCheck = true;
boolean increment = false;
int numberOfshots = 1;
int[] missiles = new int[200];
int alienBombYDelta = 0;
int alienBombXDelta = 20;
int p = 7;
boolean started = false;
final int buggyXDisplacement = 50;
boolean buggyDown = false;
int jumpHeight = 0;
int xbuggy2 = 0;
boolean down2 = true;
long lastTurn2 = System.currentTimeMillis();
long lastTurn3 = System.currentTimeMillis();
boolean jump = false;
boolean shoot = false;
int index = 0;
int missileOffSetY = 0;
boolean alienReset = false;
int score = 0;
double buggyXDistance = 0;
double distanceDelta = 1.15;
double retardation = 0.5;
boolean alienFire = false;
List<Background> backgrounds;
int spacerocki, resID, explodeID, explodeID2, alienResID2;
private volatile boolean running;
private Thread gameThread = null;
Bitmap explode, buggy, alien, explode2, spacerock;
boolean alienexplode = false;
TextView tvId;
//Activity a;
// For drawing
private Paint paint;
private Canvas canvas;
private SurfaceHolder ourHolder;
// Holds a reference to the Activity
Context context;
// Control the fps
long fps = 60;
// Screen resolution
int screenWidth;
int screenHeight;
boolean bexplode = false;
boolean brake = false;
boolean scoring = false;
class BuggyExploded extends TimerTask {
public void run() {
//Log.d("## BuggyExploded", "## BuggyExploded timer task running after 2 seconds" + buggyXDistance);
//buggy = BitmapFactory.decodeResource(context.getResources(), context.getResources().getIdentifier("vehicle",
// "drawable", context.getPackageName()));
canvas.drawBitmap(explode, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
buggyXDistance = 0;
distanceDelta = 1.15;
retardation = 0.5;
jumpHeight = 0;
waitForTimer = false;
//canvas.drawBitmap(buggy, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
}
}
class SetRecent extends TimerTask {
public void run() {
recent = false;
}
}
class ResetCheckpoint extends TimerTask {
public void run() {
Background.checkpoint = 'A';
}
}
class SetAlienBombs extends TimerTask {
public void run() {
missileOffSetY = 0;
}
}
class AlienBombed extends TimerTask {
public void run() {
alienBombXDelta = 20;
alienBombYDelta = 0;
alienReset = false;
alienexplode = false;
waitForTimer2 = false;
}
}
public void surfaceCreated(SurfaceHolder holder) {
//Canvas c = getHolder().lockCanvas();
//draw();
//getHolder().unlockCanvasAndPost(c);
}
public void surfaceDestroyed(SurfaceHolder holder3) {
//Canvas c = getHolder().lockCanvas();
//draw();
//getHolder().unlockCanvasAndPost(c);
}
public void surfaceChanged(SurfaceHolder holder, int i1, int i2, int i3) {
//Canvas c = getHolder().lockCanvas();
//draw();
//getHolder().unlockCanvasAndPost(c);
}
private void update() {
// Update all the background positions
for (Background bg : backgrounds) {
bg.update(fps);
}
}
public ParallaxView(Context c, AttributeSet a) {
super(c, a);
this.context = c;
Background.checkpoint--;
this.screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
this.screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
// Initialize our drawing objects
ourHolder = getHolder();
paint = new Paint();
// Initialize our array list
backgrounds = new ArrayList<>();
//load the background data into the Background objects and
// place them in our GameObject arraylist
backgrounds.add(new Background(
this.context,
screenWidth,
screenHeight,
"bg", 0, 120, 50));
backgrounds.add(new Background(
this.context,
screenWidth,
screenHeight,
"grass", 70, 110, 200));
//To execute the task every second after 3 s.
//Log.d("Timer", "Timer ");
resID = context.getResources().getIdentifier("vehicle",
"drawable", context.getPackageName());
explodeID = context.getResources().getIdentifier("explode",
"drawable", context.getPackageName());
explodeID2 = context.getResources().getIdentifier("explode2",
"drawable", context.getPackageName());
spacerocki = context.getResources().getIdentifier("spacerock",
"drawable", context.getPackageName());
buggy = BitmapFactory.decodeResource(context.getResources(), resID);
explode = BitmapFactory.decodeResource(context.getResources(), explodeID);
explode2 = BitmapFactory.decodeResource(context.getResources(), explodeID2);
spacerock = BitmapFactory.decodeResource(context.getResources(), spacerocki);
alienResID2 = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
alien = BitmapFactory.decodeResource(context.getResources(), alienResID2);
//resume();
//pause();
//resume();
}
#Override
public void run() {
while (running) {
long startFrameTime = System.currentTimeMillis();
update();
if (alienBombXDelta > screenWidth - 250 || alienBombXDelta < 10) { // alien ship change direction
p = -p;
}
draw();
// Calculate the fps this frame
long timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
private void checkJump() {
if (System.currentTimeMillis() - lastTurn3 >= 650) { // 650 means how long the vehicle is in the air at a jump
// Change direction here
jump = false;
lastTurn3 = System.currentTimeMillis();
}
}
private void checkBuggyBombed(Bitmap b1, Bitmap b2, Bitmap explode) {
if (!recent && java.lang.Math.abs(((buggyXDisplacement + buggyXDistance) + b1.getWidth() / 2) - (alienBombXDelta + 10 + b2.getWidth() / 2)) < b1.getWidth() / 2 && java.lang.Math.abs((alienBombYDelta + screenHeight / 100 * 25 + 75 + missileOffSetY) - ((screenHeight * 0.3) - jumpHeight + b1.getHeight())) < 65) {
bombed--;
missileOffSetY = 0;
checkpoint = 'A';
canvas.drawBitmap(explode, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
recent = true;
waitForTimer = true;
new Timer().schedule(new BuggyExploded(), 2000);
new Timer().schedule(new SetRecent(), 10000);
new Timer().schedule(new ResetCheckpoint(), 1000);
} else {
canvas.drawText("●", alienBombXDelta + 10 + b2.getWidth() / 2, alienBombYDelta + screenHeight / 100 * 25 + 75 + missileOffSetY, paint);
missileOffSetY = missileOffSetY + 10;
}
}
private void makeShots(Bitmap b) {
for (int i1 = 0; i1 < numberOfshots; i1++) {
// if vertical missile hits alien
if (java.lang.Math.abs(alienBombXDelta + 10 - 185 - buggyXDistance) * 2 < (b.getWidth() + 60) && java.lang.Math.abs(alienBombYDelta + screenHeight / 100 * 25 - (screenHeight / 100 * 95 - missiles[i1] - xbuggy2)) * 2 < (b.getHeight() + 60)) {
missileOffSetY = 9999;
canvas.drawBitmap(explode2, alienBombXDelta + 10, alienBombYDelta + screenHeight / 100 * 25, paint);
new Timer().schedule(new AlienBombed(), 2000);
waitForTimer2 = true;
if (!alienexplode) {
changeText();
}
alienexplode = true;
}
if (shoot) {
canvas.drawText("o", (float) (missiles[i1] + buggyXDistance), (float) (screenHeight * 0.7) - jumpHeight, paint); // add to y the jump height
canvas.drawText("o", (float) (buggyXDistance + 185), screenHeight / 110 * 95 - missiles[i1] - xbuggy2, paint);
}
if (i1 == numberOfshots - 1 && missiles[i1] > screenWidth) {
if (numberOfshots > 0) numberOfshots--;
if (index > 0) index--;
}
}
}
private void updateDeltas() {
alienBombXDelta = alienBombXDelta + p;
if (!down2)
alienBombYDelta++;
else
alienBombYDelta--;
}
private void changeDirections() {
if (System.currentTimeMillis() - lastTurn2 >= 7000) {
// Change direction here
down2 = !down2;
lastTurn2 = System.currentTimeMillis();
}
}
private void controlVelocity() {
if (!brake && buggyXDistance > 0) buggyXDistance = buggyXDistance + distanceDelta;
else if (brake && buggyXDistance > 0) buggyXDistance = buggyXDistance - retardation;
}
TextView tvId1;
private void drawDetails() {
//draw a background color
}
private void makeShots() {
for (int n = 0; n < numberOfshots; n++)
missiles[n] = missiles[n] + 20;
}
public void changeText() {
if (scoring) {
((Activity) this.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
score++;
String str = "Player 1 " + String.format("%06d", score);
// Stuff that updates the UI
tvId.setText(str);
scoring = false;
}
});
}
}
double lastTurn4 = System.currentTimeMillis();
private void checkFire() {
if (System.currentTimeMillis() - lastTurn4 >= 18500) { // 18500 means how often the alien fires
lastTurn4 = System.currentTimeMillis();
missileOffSetY = 0;
}
}
boolean checkpointComplete = false;
private void draw() {
if (ourHolder.getSurface().isValid()) {
//First we lock the area of memory we will be drawing to
canvas = ourHolder.lockCanvas();
if (checkpointComplete) {
canvas.drawColor(Color.BLACK);
paint.setTextSize(60);
paint.setColor(Color.argb(255, 255, 255, 255));
paint.setTextSize(60);
canvas.drawText("CHECKPOINT COMPLETE", (float) (screenWidth * 0.5), (float) (screenHeight * 0.45), paint);
((Activity) this.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
checkpointComplete = false;
}
}, 3000);
}
});
} else {
if (bombed == 0) //GAME OVER
{
final int duration = Toast.LENGTH_SHORT;
((Activity) this.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
final Toast toast = Toast.makeText(context, "GAME OVER!\nScore: " + score, duration);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
bombed = 5;
score = 0;
}
}, 3000);
}
});
}
if (jump && jumpHeight < 250) {
jumpHeight = jumpHeight + 7;
} else if (jumpHeight > 0) {
jumpHeight = jumpHeight - 4;
}
if (shoot) {
xbuggy2 = xbuggy2 + 4;
}
checkFire();
checkJump();
// drawDetails();
if (canvas != null) canvas.drawColor(Color.argb(255, 0, 0, 0));
// Draw the background parallax
drawBackground(0);
// Draw the rest of the game
paint.setTextSize(60);
paint.setColor(Color.argb(255, 255, 255, 255));
checkBuggyBombed(buggy, alien, explode);
makeShots(alien);
changeDirections();
if (!waitForTimer2)
canvas.drawBitmap(alien, alienBombXDelta + 10, alienBombYDelta + screenHeight / 100 * 25, paint);
drawBackground(1);
// canvas.drawText("X", (float) (50 + buggyXDistance)+buggy.getWidth()/2, (float) (screenHeight * 0.3) - jumpHeight+buggy.getHeight(), paint);
paint.setTextSize(60);
canvas.drawText("A E J O T Z", (float) (screenWidth * 0.7), (float) (screenHeight * 0.15), paint);
// Prevent buggy from moving outside horizontal screen
if (!brake && buggyXDisplacement + buggyXDistance > screenWidth - buggy.getWidth() - 200)
buggyXDistance = screenWidth - buggy.getWidth() - 200;
//Log.d("buggyXDistance", "buggyXDistance " + buggyXDistance);
if (!waitForTimer)
canvas.drawBitmap(buggy, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
else if (bexplode)
canvas.drawBitmap(explode, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
int inc = 0;
for (int i = 0; i < bombed; i++) {
canvas.drawBitmap(Bitmap.createScaledBitmap(buggy, (int) (0.75 * (buggy.getWidth() / 3)), buggy.getHeight() / 3, false), inc, 100, paint);
inc = inc + buggy.getWidth() / 3;
}
makeShots();
updateDeltas();
controlVelocity();
}
ourHolder.unlockCanvasAndPost(canvas);
}
}
// Clean up our thread if the game is stopped
public void pause() {
running = false;
try {
gameThread.join();
} catch (InterruptedException e) {
// Error
//e.printStackTrace();
}
}
// Make a new thread and start it
// Execution moves to our run method
public void resume() {
running = true;
gameThread = new Thread(this);
gameThread.start();
}
private void drawBackground(int position) {
// Make a copy of the relevant background
Background bg = backgrounds.get(position);
// define what portion of images to capture and
// what coordinates of screen to draw them at
// For the regular bitmap
fromRect1 = new Rect(0, 0, bg.width - bg.xClip, bg.height);
toRect1 = new Rect(bg.xClip, bg.startY, bg.width, bg.endY);
// For the reversed background
fromRect2 = new Rect(bg.width - bg.xClip, 0, bg.width, bg.height);
toRect2 = new Rect(0, bg.startY, bg.xClip, bg.endY);
// Log.d("### bg.xClip", "bg.xClip " + bg.xClip);
//draw the two background bitmaps
if (!bg.reversedFirst) {
if (canvas != null) canvas.drawBitmap(bg.bitmap, fromRect1, toRect1, paint);
if (canvas != null) canvas.drawBitmap(bg.bitmapReversed, fromRect2, toRect2, paint);
if (position == 1) { // && Background.count % 2 == 0) {
if (increment) Background.checkpoint++;
if (Background.checkpoint == 'C' && (buggyXDisplacement + buggyXDistance) < (bg.xClip) && java.lang.Math.abs((buggyXDisplacement + buggyXDistance) - (bg.xClip)) < buggy.getWidth()) { // && java.lang.Math.abs((alienBombYDelta + screenHeight / 100 * 25 + 75 + missileOffSetY) - ((screenHeight * 0.3) - jumpHeight )) < 65) {) checkpointComplete = true;
checkpointComplete=true;
}
increment = false;
if (bg.xClip == bg.width) increment = true;
if (canvas != null) canvas.drawBitmap(spacerock, fromRect1, toRect1, paint);
paint.setTextSize(160);
if (canvas != null)
canvas.drawText(Character.toString(Background.checkpoint), bg.xClip, (float) (bg.startY * 1.4), paint);
//increment checkpoint once per what? "Background.checkpoint++;"
((Activity) this.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
tvId1.setText(Character.toString(Background.checkpoint));
}
});
if (!recent && (buggyXDisplacement + buggyXDistance) < (bg.xClip) && java.lang.Math.abs((screenHeight * 0.5) - jumpHeight - bg.startY) < 180 && java.lang.Math.abs((buggyXDisplacement + buggyXDistance) - (bg.xClip)) < buggy.getWidth()) { // && java.lang.Math.abs((alienBombYDelta + screenHeight / 100 * 25 + 75 + missileOffSetY) - ((screenHeight * 0.3) - jumpHeight )) < 65) {
canvas.drawBitmap(explode, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
// Background.checkpoint = 'A';
bombed--;
recent = true;
waitForTimer = true;
bexplode = true;
canvas.drawBitmap(explode, (float) (buggyXDisplacement + buggyXDistance), (float) (screenHeight * 0.5) - jumpHeight, paint);
distanceDelta = 1.15;
retardation = 0.5;
jumpHeight = 0;
((Activity) this.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
waitForTimer = false;
buggyXDistance = 0;
}
}, 2000);
}
});
// new Timer().schedule(new BuggyExploded(), 2000);
new Timer().schedule(new SetRecent(), 10000);
new Timer().schedule(new ResetCheckpoint(), 1000);
}
}
} else {
canvas.drawBitmap(bg.bitmap, fromRect2, toRect2, paint);
canvas.drawBitmap(bg.bitmapReversed, fromRect1, toRect1, paint);
}
}
// Because we call this from onTouchEvent, this code will be executed for both
// normal touch events and for when the system calls this using Accessibility
#Override
public boolean performClick() {
super.performClick();
launchMissile();
return true;
}
protected void launchMissile() {
missiles[index] = 350; // what does it do?
index++;
xbuggy2 = 0;
shoot = true;
}
// event listener for when the user touches the screen
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean gameOver = false;
//if (paused) {
// paused = false;
//}
int action = MotionEventCompat.getActionMasked(event);
int coordX = (int) event.getX();
int coordY = (int) event.getY();
//Log.d("coordY", "coordY " + coordY);
if (coordX < 220 && jumpHeight == 0 && action == MotionEvent.ACTION_MOVE) {
jump = true;
shoot = false;
lastTurn3 = System.currentTimeMillis();
return true; // do nothing
}
if (coordX > 219 && action == MotionEvent.ACTION_DOWN) {
numberOfshots++;
performClick();
return true;
}
return true;
}
}
[
2]: https://i.stack.imgur.com/3NAmp.gif
You can follow the below code
public void setText(final String s)
{
TextView tv= (TextView) tf.getView().findViewById(R.id.textview1);
final int[] i = new int[1];
i[0] = 0;
final int length = s.length();
final Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
char c= s.charAt(i[0]);
Log.d("Strange",""+c);
tv.append(String.valueOf(c));
i[0]++;
}
};
final Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
handler.sendEmptyMessage(0);
if (i[0] == length - 1) {
timer.cancel();
}
}
};
timer.schedule(timerTask, 1, 500);
}
Think this will help you for sure
I am having a WaveFormView on which I want to change the color of it while playing Audio file and as the Audio is paused it should be stopped coloring at that certain point and when resumed it should continue forward with coloring. I am not getting how to do it in my code..
This is the screen shot of my generated waveform. Now when I will click on Play button it should change the color of waveform gradually with red color (from start to end slowly).
Here is my code to draw waveform view.
WaveFormView.class
public class WaveformView extends View {
public interface WaveformListener {
public void waveformFling(float x);
public void waveformDraw();
}
;
// Colors
private Paint mGridPaint;
private Paint mSelectedLinePaint;
private Paint mUnselectedLinePaint;
private Paint mUnselectedBkgndLinePaint;
private Paint mBorderLinePaint;
private Paint mPlaybackLinePaint;
private Paint mTimecodePaint;
private SoundFile mSoundFile;
private int[] mLenByZoomLevel;
private double[][] mValuesByZoomLevel;
private double[] mZoomFactorByZoomLevel;
private int[] mHeightsAtThisZoomLevel;
private int mZoomLevel;
private int mNumZoomLevels;
private int mSampleRate;
private int mSamplesPerFrame;
private int mOffset;
private int mSelectionStart;
private int mSelectionEnd;
private int mPlaybackPos;
private float mDensity;
private float mInitialScaleSpan;
private WaveformListener mListener;
private GestureDetector mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;
private boolean mInitialized;
Color color;
public WaveformView(Context context, AttributeSet attrs) {
super(context, attrs);
// We don't want keys, the markers get these
setFocusable(false);
mGridPaint = new Paint();
mGridPaint.setAntiAlias(false);
mGridPaint.setColor(
getResources().getColor(R.color.grid_line));
mSelectedLinePaint = new Paint();
mSelectedLinePaint.setAntiAlias(false);
mSelectedLinePaint.setColor(
getResources().getColor(R.color.waveform_selected));
mUnselectedLinePaint = new Paint();
mUnselectedLinePaint.setAntiAlias(false);
mUnselectedLinePaint.setColor(
getResources().getColor(R.color.waveform_unselected));
mUnselectedBkgndLinePaint = new Paint();
mUnselectedBkgndLinePaint.setAntiAlias(false);
mUnselectedBkgndLinePaint.setColor(
getResources().getColor(
R.color.selection_border));
mBorderLinePaint = new Paint();
mBorderLinePaint.setAntiAlias(true);
mBorderLinePaint.setStrokeWidth(1.5f);
mBorderLinePaint.setPathEffect(
new DashPathEffect(new float[]{3.0f, 2.0f}, 0.0f));
mBorderLinePaint.setColor(
getResources().getColor(R.color.selection_border));
mPlaybackLinePaint = new Paint();
mPlaybackLinePaint.setAntiAlias(false);
mPlaybackLinePaint.setColor(
getResources().getColor(R.color.playback_indicator));
mTimecodePaint = new Paint();
mTimecodePaint.setTextSize(12);
mTimecodePaint.setAntiAlias(true);
mTimecodePaint.setColor(
getResources().getColor(R.color.timecode));
mTimecodePaint.setShadowLayer(
2, 1, 1,
getResources().getColor(R.color.timecode_shadow));
mGestureDetector = new GestureDetector(
context,
new GestureDetector.SimpleOnGestureListener() {
public boolean onFling(
MotionEvent e1, MotionEvent e2, float vx, float vy) {
mListener.waveformFling(vx);
return true;
}
});
mSoundFile = null;
mLenByZoomLevel = null;
mValuesByZoomLevel = null;
mHeightsAtThisZoomLevel = null;
mOffset = 0;
mPlaybackPos = -1;
mSelectionStart = 0;
mSelectionEnd = 0;
mDensity = 1.0f;
mInitialized = false;
}
public boolean hasSoundFile() {
return mSoundFile != null;
}
public void setSoundFile(SoundFile soundFile) {
mSoundFile = soundFile;
mSampleRate = mSoundFile.getSampleRate();
mSamplesPerFrame = mSoundFile.getSamplesPerFrame();
computeDoublesForAllZoomLevels();
mHeightsAtThisZoomLevel = null;
}
/**
* Called once when a new sound file is added
*/
private void computeDoublesForAllZoomLevels() {
int numFrames = mSoundFile.getNumFrames();
int[] frameGains = mSoundFile.getFrameGains();
double[] smoothedGains = new double[numFrames];
if (numFrames == 1) {
smoothedGains[0] = frameGains[0];
} else if (numFrames == 2) {
smoothedGains[0] = frameGains[0];
smoothedGains[1] = frameGains[1];
} else if (numFrames > 2) {
smoothedGains[0] = (double)(
(frameGains[0] / 2.0) +
(frameGains[1] / 2.0));
for (int i = 1; i < numFrames - 1; i++) {
smoothedGains[i] = (double)(
(frameGains[i - 1] / 3.0) +
(frameGains[i ] / 3.0) +
(frameGains[i + 1] / 3.0));
}
smoothedGains[numFrames - 1] = (double)(
(frameGains[numFrames - 2] / 2.0) +
(frameGains[numFrames - 1] / 2.0));
}
// Make sure the range is no more than 0 - 255
double maxGain = 1.0;
for (int i = 0; i < numFrames; i++) {
if (smoothedGains[i] > maxGain) {
maxGain = smoothedGains[i];
}
}
double scaleFactor = 1.0;
if (maxGain > 255.0) {
scaleFactor = 255 / maxGain;
}
// Build histogram of 256 bins and figure out the new scaled max
maxGain = 0;
int gainHist[] = new int[256];
for (int i = 0; i < numFrames; i++) {
int smoothedGain = (int)(smoothedGains[i] * scaleFactor);
if (smoothedGain < 0)
smoothedGain = 0;
if (smoothedGain > 255)
smoothedGain = 255;
if (smoothedGain > maxGain)
maxGain = smoothedGain;
gainHist[smoothedGain]++;
}
// Re-calibrate the min to be 5%
double minGain = 0;
int sum = 0;
while (minGain < 255 && sum < numFrames / 20) {
sum += gainHist[(int)minGain];
minGain++;
}
// Re-calibrate the max to be 99%
sum = 0;
while (maxGain > 2 && sum < numFrames / 100) {
sum += gainHist[(int)maxGain];
maxGain--;
}
// Compute the heights
double[] heights = new double[numFrames];
double range = maxGain - minGain;
for (int i = 0; i < numFrames; i++) {
double value = (smoothedGains[i] * scaleFactor - minGain) / range;
if (value < 0.0)
value = 0.0;
if (value > 1.0)
value = 1.0;
heights[i] = value * value;
}
mNumZoomLevels = 5;
mLenByZoomLevel = new int[5];
mZoomFactorByZoomLevel = new double[5];
mValuesByZoomLevel = new double[5][];
// Level 0 is doubled, with interpolated values
mLenByZoomLevel[0] = numFrames * 2;
mZoomFactorByZoomLevel[0] = 2.0;
mValuesByZoomLevel[0] = new double[mLenByZoomLevel[0]];
if (numFrames > 0) {
mValuesByZoomLevel[0][0] = 0.5 * heights[0];
mValuesByZoomLevel[0][1] = heights[0];
}
for (int i = 1; i < numFrames; i++) {
mValuesByZoomLevel[0][2 * i] = 0.5 * (heights[i - 1] + heights[i]);
mValuesByZoomLevel[0][2 * i + 1] = heights[i];
}
// Level 1 is normal
mLenByZoomLevel[1] = numFrames;
mValuesByZoomLevel[1] = new double[mLenByZoomLevel[1]];
mZoomFactorByZoomLevel[1] = 1.0;
for (int i = 0; i < mLenByZoomLevel[1]; i++) {
mValuesByZoomLevel[1][i] = heights[i];
}
// 3 more levels are each halved
for (int j = 2; j < 5; j++) {
mLenByZoomLevel[j] = mLenByZoomLevel[j - 1] / 2;
mValuesByZoomLevel[j] = new double[mLenByZoomLevel[j]];
mZoomFactorByZoomLevel[j] = mZoomFactorByZoomLevel[j - 1] / 2.0;
for (int i = 0; i < mLenByZoomLevel[j]; i++) {
mValuesByZoomLevel[j][i] =
0.5 * (mValuesByZoomLevel[j - 1][2 * i] +
mValuesByZoomLevel[j - 1][2 * i + 1]);
}
}
if (numFrames > 5000) {
mZoomLevel = 3;
} else if (numFrames > 1000) {
mZoomLevel = 2;
} else if (numFrames > 300) {
mZoomLevel = 1;
} else {
mZoomLevel = 0;
}
mInitialized = true;
}
public boolean canZoomIn() {
return (mZoomLevel > 0);
}
public void zoomIn() {
if (canZoomIn()) {
mZoomLevel--;
mSelectionStart *= 2;
mSelectionEnd *= 2;
mHeightsAtThisZoomLevel = null;
int offsetCenter = mOffset + getMeasuredWidth() / 2;
offsetCenter *= 2;
mOffset = offsetCenter - getMeasuredWidth() / 2;
if (mOffset < 0)
mOffset = 0;
invalidate();
}
}
public boolean canZoomOut() {
return (mZoomLevel < mNumZoomLevels - 1);
}
public void zoomOut() {
if (canZoomOut()) {
mZoomLevel++;
mSelectionStart /= 2;
mSelectionEnd /= 2;
int offsetCenter = mOffset + getMeasuredWidth() / 2;
offsetCenter /= 2;
mOffset = offsetCenter - getMeasuredWidth() / 2;
if (mOffset < 0)
mOffset = 0;
mHeightsAtThisZoomLevel = null;
invalidate();
}
}
public double pixelsToSeconds(int pixels) {
double z = mZoomFactorByZoomLevel[mZoomLevel];
return (pixels * (double)mSamplesPerFrame / (mSampleRate * z));
}
public void setListener(WaveformListener listener) {
mListener = listener;
}
public void recomputeHeights(float density) {
mHeightsAtThisZoomLevel = null;
mDensity = density;
mTimecodePaint.setTextSize((int)(12 * density));
invalidate();
}
protected void drawWaveformLine(Canvas canvas,
int x, int y0, int y1,
Paint paint) {
canvas.drawLine(x, y0, x, y1, paint);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mSoundFile == null)
return;
if (mHeightsAtThisZoomLevel == null)
computeIntsForThisZoomLevel();
DisplayMetrics displaymetrics = getContext().getResources().getDisplayMetrics();
int height = displaymetrics.heightPixels;
int widths = displaymetrics.widthPixels;
// Draw waveform
int measuredWidth = getMeasuredWidth();
int measuredHeight = getMeasuredHeight();
int start = mOffset;
int width = mHeightsAtThisZoomLevel.length - start;
int ctr = measuredHeight / 2;
Log.e("wid",String.valueOf(width));
Log.e("widCal",String.valueOf(mHeightsAtThisZoomLevel.length));
Log.e("widstart",String.valueOf(start));
if (width > measuredWidth)
width = measuredWidth;
Log.e("measured",String.valueOf(measuredWidth));
// Draw grid
double onePixelInSecs = pixelsToSeconds(1);
boolean onlyEveryFiveSecs = (onePixelInSecs > 1.0 / 50.0);
double fractionalSecs = mOffset * onePixelInSecs;
int integerSecs = (int) fractionalSecs;
int i = 0;
while (i < width) {
i++;
fractionalSecs += onePixelInSecs;
int integerSecsNew = (int) fractionalSecs;
if (integerSecsNew != integerSecs) {
integerSecs = integerSecsNew;
if (!onlyEveryFiveSecs || 0 == (integerSecs % 5)) {
canvas.drawLine(i, 0, i, measuredHeight, mGridPaint);
}
}
}
// Draw waveform
for ( i = 0; i < width; i++) {
Paint paint;
if (i + start >= mSelectionStart &&
i + start < mSelectionEnd) {
paint = mSelectedLinePaint;
// paint.setColor(color);
} else {
drawWaveformLine(canvas, ((widths/width)*i), 0, measuredHeight,
mUnselectedBkgndLinePaint);
paint = mUnselectedLinePaint;
}
drawWaveformLine(
canvas, ((widths/width)*i),
ctr - mHeightsAtThisZoomLevel[start + i],
ctr + 1 + mHeightsAtThisZoomLevel[start + i],
paint);
if (i + start == mPlaybackPos) {
canvas.drawLine(i, 0, i, measuredHeight, mPlaybackLinePaint);
}
}
if (mListener != null) {
mListener.waveformDraw();
}
}
private void computeIntsForThisZoomLevel() {
int halfHeight = (getMeasuredHeight() / 2) - 1;
mHeightsAtThisZoomLevel = new int[mLenByZoomLevel[mZoomLevel]];
for (int i = 0; i < mLenByZoomLevel[mZoomLevel]; i++) {
mHeightsAtThisZoomLevel[i] =
(int)(mValuesByZoomLevel[mZoomLevel][i] * halfHeight);
}
}
}
MainActivity.class
public class MainActivity extends AppCompatActivity implements WaveformView.WaveformListener {
WaveformView mWaveformView;
SoundFile mSoundFile;
private float mDensity;
private File mFile;
private String mFilename;
private long mLoadingLastUpdateTime;
boolean mLoadingKeepGoing;
boolean mFinishActivity;
private ProgressDialog mProgressDialog;
String mTitle,mArtist;
private Thread mLoadSoundFileThread;
private Thread mRecordAudioThread;
private Thread mSaveSoundFileThread;
private boolean mIsPlaying;
private SamplePlayer mPlayer;
private String mInfoContent;
private int mWidth;
private int mMaxPos;
private int mStartPos;
private int mEndPos;
private boolean mStartVisible;
private boolean mEndVisible;
private int mLastDisplayedStartPos;
private int mLastDisplayedEndPos;
private int mOffset;
private int mOffsetGoal;
private int mFlingVelocity;
private int mPlayStartMsec;
private int mPlayEndMsec;
private Handler mHandler;
Button pla;
MediaPlayer mediaPlayer;
boolean ismIsPlaying;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pla = (Button)findViewById(R.id.play);
mWaveformView = (WaveformView)findViewById(R.id.waveform);
mWaveformView.setListener(this);
mHandler = new Handler();
Uri uri = Uri.parse("/sdcard/audio_file.mp3");
mediaPlayer = new MediaPlayer();
mediaPlayer = MediaPlayer.create(getApplicationContext(),uri);
loadGui();
loadFromFile();
}
/**
* Called from both onCreate and onConfigurationChanged
* (if the user switched layouts)
*/
private void loadGui() {
// Inflate our UI from its XML layout description.
setContentView(R.layout.activity_main);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mDensity = metrics.density;
mWaveformView = (WaveformView)findViewById(R.id.waveform);
mWaveformView.setListener(this);
if (mSoundFile != null && !mWaveformView.hasSoundFile()) {
mWaveformView.setSoundFile(mSoundFile);
mWaveformView.recomputeHeights(mDensity);
}
}
private void loadFromFile() {
mFilename = "/sdcard/audio_file.mp3";
mFile = new File(mFilename);
SongMetadataReader metadataReader = new SongMetadataReader(
this, mFilename);
mTitle = metadataReader.mTitle;
mArtist = metadataReader.mArtist;
String titleLabel = mTitle;
if (mArtist != null && mArtist.length() > 0) {
titleLabel += " - " + mArtist;
}
setTitle(titleLabel);
mLoadingLastUpdateTime = getCurrentTime();
mLoadingKeepGoing = true;
mFinishActivity = false;
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setTitle("Loading...");
mProgressDialog.setCancelable(true);
mProgressDialog.setOnCancelListener(
new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
mLoadingKeepGoing = false;
mFinishActivity = true;
}
});
mProgressDialog.show();
final SoundFile.ProgressListener listener =
new SoundFile.ProgressListener() {
public boolean reportProgress(double fractionComplete) {
long now = getCurrentTime();
if (now - mLoadingLastUpdateTime > 100) {
mProgressDialog.setProgress(
(int) (mProgressDialog.getMax() * fractionComplete));
mLoadingLastUpdateTime = now;
}
return mLoadingKeepGoing;
}
};
// Load the sound file in a background thread
mLoadSoundFileThread = new Thread() {
public void run() {
try {
mSoundFile = SoundFile.create(mFile.getAbsolutePath(), listener);
if (mSoundFile == null) {
mProgressDialog.dismiss();
String name = mFile.getName().toLowerCase();
String[] components = name.split("\\.");
String err;
if (components.length < 2) {
err = getResources().getString(
R.string.no_extension_error);
} else {
err = getResources().getString(
R.string.bad_extension_error) + " " +
components[components.length - 1];
}
final String finalErr = err;
Runnable runnable = new Runnable() {
public void run() {
showFinalAlert(new Exception(), finalErr);
}
};
mHandler.post(runnable);
return;
}
mPlayer = new SamplePlayer(mSoundFile);
} catch (final Exception e) {
mProgressDialog.dismiss();
e.printStackTrace();
mInfoContent = e.toString();
runOnUiThread(new Runnable() {
public void run() {
}
});
Runnable runnable = new Runnable() {
public void run() {
showFinalAlert(e, getResources().getText(R.string.read_error));
}
};
mHandler.post(runnable);
return;
}
mProgressDialog.dismiss();
if (mLoadingKeepGoing) {
Runnable runnable = new Runnable() {
public void run() {
finishOpeningSoundFile();
}
};
mHandler.post(runnable);
} else if (mFinishActivity){
MainActivity.this.finish();
}
}
};
mLoadSoundFileThread.start();
}
private void finishOpeningSoundFile() {
mWaveformView.setSoundFile(mSoundFile);
mWaveformView.recomputeHeights(mDensity);
Log.e("sound file",mFilename);
Log.e("sound", String.valueOf(mSoundFile));
}
/**
* Show a "final" alert dialog that will exit the activity
* after the user clicks on the OK button. If an exception
* is passed, it's assumed to be an error condition, and the
* dialog is presented as an error, and the stack trace is
* logged. If there's no exception, it's a success message.
*/
private void showFinalAlert(Exception e, CharSequence message) {
CharSequence title;
if (e != null) {
Log.e("Ringdroid", "Error: " + message);
Log.e("Ringdroid", getStackTrace(e));
title = getResources().getText(R.string.alert_title_failure);
setResult(RESULT_CANCELED, new Intent());
} else {
Log.v("Ringdroid", "Success: " + message);
title = getResources().getText(R.string.alert_title_success);
}
new AlertDialog.Builder(MainActivity.this)
.setTitle(title)
.setMessage(message)
.setPositiveButton(
R.string.alert_ok_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
finish();
}
})
.setCancelable(false)
.show();
}
private void showFinalAlert(Exception e, int messageResourceId) {
showFinalAlert(e, getResources().getText(messageResourceId));
}
#Override
public void waveformTouchStart(float x) {
}
#Override
public void waveformTouchMove(float x) {
}
#Override
public void waveformTouchEnd() {
}
#Override
public void waveformFling(float x) {
}
#Override
public void waveformDraw() {
mWidth = mWaveformView.getMeasuredWidth();
if (mOffsetGoal != mOffset) {
// updateDisplay();
}
else if (mIsPlaying) {
// updateDisplay();
} else if (mFlingVelocity != 0) {
// updateDisplay();
}
}
private long getCurrentTime() {
return System.nanoTime() / 1000000;
}
private String getStackTrace(Exception e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
public void buttonClick(View view) {
Toast.makeText(MainActivity.this, "test", Toast.LENGTH_SHORT).show();
mediaPlayer.start();
ismIsPlaying = true;
}
}
In your onDraw(Canvas canvas) add the following lines
if (i + start <= mPlaybackPos) {
Paint mPaint = new Paint(paint);
mPaint.setColor(Color.RED);
drawWaveformLine(
canvas, ((widths/width)*i),
ctr - mHeightsAtThisZoomLevel[start + i],
ctr + 1 + mHeightsAtThisZoomLevel[start + i],
mPaint);
}
add them above the line:
if (i + start == mPlaybackPos) {
And if this works, consider to allocate the Paint-object outside the onDraw() method.
Basically, I cloned a material design widget library and wanted to use the Seekbar view. Even when using match_parent for the width, there was still some padding on the left and right. To combat this, I cloned the project from GitHub and went to the Slider.java class to try and figure out how to truly make this a full length media SeekBar.
I've included my current code, which basically shows a full length seekbar, but starts it a little to the right from the beginning (and consequently stops a little to the left from the end). Here it is mid-media-playback:
CODE
public class Slider extends CustomView {
private int backgroundColor = Color.parseColor("#614E8D");
private Ball ball;
private Bitmap bitmap;
private int max = 100;
private int min = 0;
private NumberIndicator numberIndicator;
private OnValueChangedListener onValueChangedListener;
private boolean placedBall = false;
private boolean press = false;
private boolean showNumberIndicator = false;
private int value = 0;
public Slider(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(attrs);
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getMin() {
return min;
}
public void setMin(int min) {
this.min = min;
}
public OnValueChangedListener getOnValueChangedListener() {
return onValueChangedListener;
}
public void setOnValueChangedListener(
OnValueChangedListener onValueChangedListener) {
this.onValueChangedListener = onValueChangedListener;
}
// GETERS & SETTERS
public int getValue() {
return value;
}
public void setValue(final int value) {
if (placedBall == false)
post(new Runnable() {
#Override
public void run() {
setValue(value);
}
});
else {
this.value = value;
float division = (ball.xFin - ball.xIni) / max;
ViewHelper.setX(ball,
value * division + getHeight() / 2 - ball.getWidth() / 2);
ball.changeBackground();
}
}
#Override
public void invalidate() {
ball.invalidate();
super.invalidate();
}
public boolean isShowNumberIndicator() {
return showNumberIndicator;
}
public void setShowNumberIndicator(boolean showNumberIndicator) {
this.showNumberIndicator = showNumberIndicator;
numberIndicator = (showNumberIndicator) ? new NumberIndicator(
getContext()) : null;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
isLastTouch = true;
if (isEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN
|| event.getAction() == MotionEvent.ACTION_MOVE) {
if (numberIndicator != null
&& numberIndicator.isShowing() == false)
numberIndicator.show();
if ((event.getX() <= getWidth() && event.getX() >= 0)) {
press = true;
// calculate value
int newValue = 0;
float division = (ball.xFin - ball.xIni) / (max - min);
if (event.getX() > ball.xFin) {
newValue = max;
} else if (event.getX() < ball.xIni) {
newValue = min;
} else {
newValue = min + (int) ((event.getX() - ball.xIni) / division);
}
if (value != newValue) {
value = newValue;
if (onValueChangedListener != null)
onValueChangedListener.onValueChanged(newValue);
}
// move ball indicator
float x = event.getX();
x = (x < ball.xIni) ? ball.xIni : x;
x = (x > ball.xFin) ? ball.xFin : x;
ViewHelper.setX(ball, x);
ball.changeBackground();
// If slider has number indicator
if (numberIndicator != null) {
// move number indicator
numberIndicator.indicator.x = x;
numberIndicator.indicator.finalY = Utils
.getRelativeTop(this) - getHeight() / 2;
numberIndicator.indicator.finalSize = getHeight() / 2;
numberIndicator.numberIndicator.setText("");
}
} else {
press = false;
isLastTouch = false;
if (numberIndicator != null)
numberIndicator.dismiss();
}
} else if (event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_CANCEL) {
if (numberIndicator != null)
numberIndicator.dismiss();
isLastTouch = false;
press = false;
}
}
return true;
}
#Override
public void setBackgroundColor(int color) {
backgroundColor = color;
if (isEnabled())
beforeBackground = backgroundColor;
}
/**
* Make a dark color to press effect
*
* #return
*/
protected int makePressColor() {
int r = (this.backgroundColor >> 16) & 0xFF;
int g = (this.backgroundColor >> 8) & 0xFF;
int b = (this.backgroundColor >> 0) & 0xFF;
r = (r - 30 < 0) ? 0 : r - 30;
g = (g - 30 < 0) ? 0 : g - 30;
b = (b - 30 < 0) ? 0 : b - 30;
return Color.argb(70, r, g, b);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!placedBall) {
placeBall();
}
Paint paint = new Paint();
if (value == min) {
// Crop line to transparent effect
// before song loaded, basically. Need to make this similar to value != min
if (bitmap == null) {
bitmap = Bitmap.createBitmap(canvas.getWidth(),
canvas.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas temp = new Canvas(bitmap);
paint.setColor(Color.parseColor("#54457A")); //purple
paint.setStrokeWidth(Utils.dpToPx(2, getResources()));
// temp.drawLine(getHeight() / 2, getHeight() / 2, getWidth()
// - getHeight() / 2, getHeight() / 2, paint);
temp.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2, paint);
Paint transparentPaint = new Paint();
transparentPaint.setColor(getResources().getColor(
android.R.color.transparent));
transparentPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
temp.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2,
ViewHelper.getY(ball) + ball.getHeight() / 2,
ball.getWidth() / 2, transparentPaint);
canvas.drawBitmap(bitmap, 0, 0, new Paint());
} else {
/*TRACK*/
paint.setColor(Color.parseColor("#5A5A5C")); //track
paint.setStrokeWidth(Utils.dpToPx(10, getResources()));
canvas.drawLine(0, getHeight()/2, getWidth(), getHeight()/2, paint); //track length
paint.setColor(backgroundColor);
/*END TRACK*/
float division = (ball.xFin - ball.xIni) / (max - min);
int value = this.value - min;
//DO NOT TOUCH -- Progress coloring
canvas.drawLine(getHeight() / 2, getHeight() / 2, value * division
+ getHeight() / 2, getHeight() / 2, paint);
}
if (press && !showNumberIndicator) {
paint.setColor(backgroundColor);
paint.setAntiAlias(true);
canvas.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2,
getHeight() / 2, getHeight() / 3, paint);
}
invalidate();
}
// Set atributtes of XML to View
protected void setAttributes(AttributeSet attrs) {
setBackgroundResource(R.drawable.background_transparent);
// Set size of view
setMinimumHeight(Utils.dpToPx(48, getResources()));
setMinimumWidth(Utils.dpToPx(80, getResources()));
// Set background Color
// Color by resource
int bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML,
"background", -1);
if (bacgroundColor != -1) {
setBackgroundColor(getResources().getColor(bacgroundColor));
} else {
// Color by hexadecimal
int background = attrs.getAttributeIntValue(ANDROIDXML, "background", -1);
if (background != -1)
setBackgroundColor(background);
}
showNumberIndicator = attrs.getAttributeBooleanValue(MATERIALDESIGNXML,
"showNumberIndicator", false);
min = attrs.getAttributeIntValue(MATERIALDESIGNXML, "min", 0);
max = attrs.getAttributeIntValue(MATERIALDESIGNXML, "max", 0);
value = attrs.getAttributeIntValue(MATERIALDESIGNXML, "value", min);
ball = new Ball(getContext());
RelativeLayout.LayoutParams params = new LayoutParams(Utils.dpToPx(20,
getResources()), Utils.dpToPx(20, getResources()));
params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
ball.setLayoutParams(params);
addView(ball);
// Set if slider content number indicator
// TODO
if (showNumberIndicator) {
numberIndicator = new NumberIndicator(getContext());
}
}
private void placeBall() {
ViewHelper.setX(ball, getHeight() / 2 - ball.getWidth() / 2);
ViewHelper.setX(ball, ball.getWidth());
ball.xIni = ViewHelper.getX(ball);
ball.xFin = getWidth() - ball.getWidth();// - getHeight() / 2 - ball.getWidth() / 2;
ball.xCen = getWidth() / 2 - ball.getWidth() / 2;
placedBall = true;
}
// Event when slider change value
public interface OnValueChangedListener {
public void onValueChanged(int value);
}
class Ball extends View {
float xIni, xFin, xCen;
public Ball(Context context) {
super(context);
setBackgroundResource(R.drawable.background_switch_ball_uncheck);
}
public void changeBackground() {
if (value != min) {
setBackgroundResource(R.drawable.background_checkbox);
LayerDrawable layer = (LayerDrawable) getBackground();
GradientDrawable shape = (GradientDrawable) layer
.findDrawableByLayerId(R.id.shape_bacground);
shape.setColor(Color.parseColor("#D5C46A")); //yellow ball
} else {
setBackgroundResource(R.drawable.background_switch_ball_uncheck);
}
}
}
// Slider Number Indicator
class Indicator extends RelativeLayout {
boolean animate = true;
// Final size after animation
float finalSize = 0;
// Final y position after animation
float finalY = 0;
boolean numberIndicatorResize = false;
// Size of number indicator
float size = 0;
// Position of number indicator
float x = 0;
float y = 0;
public Indicator(Context context) {
super(context);
setBackgroundColor(getResources().getColor(
android.R.color.transparent));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (numberIndicatorResize == false) {
LayoutParams params = (LayoutParams) numberIndicator.numberIndicator
.getLayoutParams();
params.height = (int) finalSize * 2;
params.width = (int) finalSize * 2;
numberIndicator.numberIndicator.setLayoutParams(params);
}
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(backgroundColor);
if (animate) {
if (y == 0)
y = finalY + finalSize * 2;
y -= Utils.dpToPx(6, getResources());
size += Utils.dpToPx(2, getResources());
}
canvas.drawCircle(
ViewHelper.getX(ball)
+ Utils.getRelativeLeft((View) ball.getParent())
+ ball.getWidth() / 2, y, size, paint);
if (animate && size >= finalSize)
animate = false;
if (animate == false) {
ViewHelper
.setX(numberIndicator.numberIndicator,
(ViewHelper.getX(ball)
+ Utils.getRelativeLeft((View) ball
.getParent()) + ball.getWidth() / 2)
- size);
ViewHelper.setY(numberIndicator.numberIndicator, y - size);
numberIndicator.numberIndicator.setText(value + "");
}
invalidate();
}
}
class NumberIndicator extends Dialog {
Indicator indicator;
TextView numberIndicator;
public NumberIndicator(Context context) {
super(context, android.R.style.Theme_Translucent);
}
#Override
public void dismiss() {
super.dismiss();
indicator.y = 0;
indicator.size = 0;
indicator.animate = true;
}
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.number_indicator_spinner);
setCanceledOnTouchOutside(false);
RelativeLayout content = (RelativeLayout) this
.findViewById(R.id.number_indicator_spinner_content);
indicator = new Indicator(this.getContext());
content.addView(indicator);
numberIndicator = new TextView(getContext());
numberIndicator.setTextColor(Color.WHITE);
numberIndicator.setGravity(Gravity.CENTER);
content.addView(numberIndicator);
indicator.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
}
}
}
Any help on how to get the circle to start at the very left and end at the very right would be greatly appreciated.
Playing around some more, I found that the original developer of this Slider.java class used a lot of getHeight() / 2 which caused some padding that I didn't want. I've included the edited class. Credit for original class to navasmdc, the creator of Material Design Library.. Feel free to use this class if you need a full sized SeekBar
Slider.java
package com.gc.materialdesign.views;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.gc.materialdesign.R;
import com.gc.materialdesign.utils.Utils;
import com.nineoldandroids.view.ViewHelper;
public class Slider extends CustomView {
private int backgroundColor = Color.parseColor("#614E8D");
private Ball ball;
private Bitmap bitmap;
private int max = 100;
private int min = 0;
private NumberIndicator numberIndicator;
private OnValueChangedListener onValueChangedListener;
private boolean placedBall = false;
private boolean press = false;
private boolean showNumberIndicator = false;
private int value = 0;
public Slider(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(attrs);
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getMin() {
return min;
}
public void setMin(int min) {
this.min = min;
}
public OnValueChangedListener getOnValueChangedListener() {
return onValueChangedListener;
}
public void setOnValueChangedListener(
OnValueChangedListener onValueChangedListener) {
this.onValueChangedListener = onValueChangedListener;
}
// GETERS & SETTERS
public int getValue() {
return value;
}
public void setValue(final int value) {
if (placedBall == false)
post(new Runnable() {
#Override
public void run() {
setValue(value);
}
});
else {
this.value = value;
float division = (ball.xFin - ball.xIni) / max;
ViewHelper.setX(ball,
value* division);//value * division - ball.getWidth() / 2);
ball.changeBackground();
}
}
#Override
public void invalidate() {
ball.invalidate();
super.invalidate();
}
public boolean isShowNumberIndicator() {
return showNumberIndicator;
}
public void setShowNumberIndicator(boolean showNumberIndicator) {
this.showNumberIndicator = showNumberIndicator;
numberIndicator = (showNumberIndicator) ? new NumberIndicator(
getContext()) : null;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
isLastTouch = true;
if (isEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN
|| event.getAction() == MotionEvent.ACTION_MOVE) {
if (numberIndicator != null
&& numberIndicator.isShowing() == false)
numberIndicator.show();
if ((event.getX() <= getWidth() && event.getX() >= 0)) {
press = true;
// calculate value
int newValue = 0;
float division = (ball.xFin - ball.xIni) / (max - min);
if (event.getX() > ball.xFin) {
newValue = max;
} else if (event.getX() < ball.xIni) {
newValue = min;
} else {
newValue = min + (int) ((event.getX() - ball.xIni) / division);
}
if (value != newValue) {
value = newValue;
if (onValueChangedListener != null)
onValueChangedListener.onValueChanged(newValue);
}
// move ball indicator
float x = event.getX();
x = (x < ball.xIni) ? ball.xIni : x;
x = (x > ball.xFin) ? ball.xFin : x;
ViewHelper.setX(ball, x);
ball.changeBackground();
// If slider has number indicator
if (numberIndicator != null) {
// move number indicator
numberIndicator.indicator.x = x;
numberIndicator.indicator.finalY = Utils
.getRelativeTop(this) - getHeight() / 2;
numberIndicator.indicator.finalSize = getHeight() / 2;
numberIndicator.numberIndicator.setText("");
}
} else {
press = false;
isLastTouch = false;
if (numberIndicator != null)
numberIndicator.dismiss();
}
} else if (event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_CANCEL) {
if (numberIndicator != null)
numberIndicator.dismiss();
isLastTouch = false;
press = false;
}
}
return true;
}
#Override
public void setBackgroundColor(int color) {
backgroundColor = color;
if (isEnabled())
beforeBackground = backgroundColor;
}
/**
* Make a dark color to press effect
*
* #return
*/
protected int makePressColor() {
int r = (this.backgroundColor >> 16) & 0xFF;
int g = (this.backgroundColor >> 8) & 0xFF;
int b = (this.backgroundColor >> 0) & 0xFF;
r = (r - 30 < 0) ? 0 : r - 30;
g = (g - 30 < 0) ? 0 : g - 30;
b = (b - 30 < 0) ? 0 : b - 30;
return Color.argb(70, r, g, b);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!placedBall) {
placeBall();
}
Paint paint = new Paint();
if (value == min) {
// Crop line to transparent effect
// before song loaded, basically. Need to make this similar to value != min
if (bitmap == null) {
bitmap = Bitmap.createBitmap(canvas.getWidth(),
canvas.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas temp = new Canvas(bitmap);
paint.setColor(Color.parseColor("#54457A")); //purple
paint.setStrokeWidth(Utils.dpToPx(2, getResources()));
// temp.drawLine(getHeight() / 2, getHeight() / 2, getWidth()
// - getHeight() / 2, getHeight() / 2, paint);
temp.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2, paint);
Paint transparentPaint = new Paint();
transparentPaint.setColor(getResources().getColor(
android.R.color.transparent));
transparentPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
temp.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2,
ViewHelper.getY(ball) + ball.getHeight() / 2,
ball.getWidth() / 2, transparentPaint);
canvas.drawBitmap(bitmap, 0, 0, new Paint());
} else {
/*TRACK*/
paint.setColor(Color.parseColor("#5A5A5C")); //track
paint.setStrokeWidth(Utils.dpToPx(10, getResources()));
canvas.drawLine(0, getHeight()/2, getWidth(), getHeight()/2, paint); //track length
paint.setColor(backgroundColor);
/*END TRACK*/
float division = (ball.xFin - ball.xIni) / (max - min);
int value = this.value - min;
//DO NOT TOUCH -- Progress coloring
canvas.drawLine(0, getHeight() / 2, value * division
+ball.getWidth(), getHeight() / 2, paint);
}
if (press && !showNumberIndicator) {
paint.setColor(backgroundColor);
paint.setAntiAlias(true);
canvas.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2,
getHeight() / 2, getHeight() / 3, paint);
}
invalidate();
}
// Set atributtes of XML to View
protected void setAttributes(AttributeSet attrs) {
setBackgroundResource(R.drawable.background_transparent);
// Set size of view
setMinimumHeight(Utils.dpToPx(48, getResources()));
setMinimumWidth(Utils.dpToPx(80, getResources()));
// Set background Color
// Color by resource
int bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML,
"background", -1);
if (bacgroundColor != -1) {
setBackgroundColor(getResources().getColor(bacgroundColor));
} else {
// Color by hexadecimal
int background = attrs.getAttributeIntValue(ANDROIDXML, "background", -1);
if (background != -1)
setBackgroundColor(background);
}
showNumberIndicator = attrs.getAttributeBooleanValue(MATERIALDESIGNXML,
"showNumberIndicator", false);
min = attrs.getAttributeIntValue(MATERIALDESIGNXML, "min", 0);
max = attrs.getAttributeIntValue(MATERIALDESIGNXML, "max", 0);
value = attrs.getAttributeIntValue(MATERIALDESIGNXML, "value", min);
ball = new Ball(getContext());
RelativeLayout.LayoutParams params = new LayoutParams(Utils.dpToPx(20,
getResources()), Utils.dpToPx(20, getResources()));
params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
ball.setLayoutParams(params);
addView(ball);
// Set if slider content number indicator
// TODO
if (showNumberIndicator) {
numberIndicator = new NumberIndicator(getContext());
}
}
private void placeBall() {
// ViewHelper.setX(ball, getHeight() / 2 - ball.getWidth() / 2);
// ViewHelper.setX(ball, 0);
ViewHelper.setX(ball, ball.getWidth());
ball.xIni = 0;//ViewHelper.getX(ball);
ball.xFin = getWidth() - ball.getWidth();// - getHeight() / 2 - ball.getWidth() / 2;
ball.xCen = getWidth() / 2 - ball.getWidth() / 2;
placedBall = true;
}
// Event when slider change value
public interface OnValueChangedListener {
public void onValueChanged(int value);
}
class Ball extends View {
float xIni, xFin, xCen;
public Ball(Context context) {
super(context);
setBackgroundResource(R.drawable.background_switch_ball_uncheck);
}
public void changeBackground() {
if (value != min) {
setBackgroundResource(R.drawable.background_checkbox);
LayerDrawable layer = (LayerDrawable) getBackground();
GradientDrawable shape = (GradientDrawable) layer
.findDrawableByLayerId(R.id.shape_bacground);
shape.setColor(Color.parseColor("#D5C46A")); //yellow ball
} else {
setBackgroundResource(R.drawable.background_switch_ball_uncheck);
}
}
}
// Slider Number Indicator
class Indicator extends RelativeLayout {
boolean animate = true;
// Final size after animation
float finalSize = 0;
// Final y position after animation
float finalY = 0;
boolean numberIndicatorResize = false;
// Size of number indicator
float size = 0;
// Position of number indicator
float x = 0;
float y = 0;
public Indicator(Context context) {
super(context);
setBackgroundColor(getResources().getColor(
android.R.color.transparent));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (numberIndicatorResize == false) {
LayoutParams params = (LayoutParams) numberIndicator.numberIndicator
.getLayoutParams();
params.height = (int) finalSize * 2;
params.width = (int) finalSize * 2;
numberIndicator.numberIndicator.setLayoutParams(params);
}
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(backgroundColor);
if (animate) {
if (y == 0)
y = finalY + finalSize * 2;
y -= Utils.dpToPx(6, getResources());
size += Utils.dpToPx(2, getResources());
}
canvas.drawCircle(
ViewHelper.getX(ball)
+ Utils.getRelativeLeft((View) ball.getParent())
+ ball.getWidth() / 2, y, size, paint);
if (animate && size >= finalSize)
animate = false;
if (animate == false) {
ViewHelper
.setX(numberIndicator.numberIndicator,
(ViewHelper.getX(ball)
+ Utils.getRelativeLeft((View) ball
.getParent()) + ball.getWidth() / 2)
- size);
ViewHelper.setY(numberIndicator.numberIndicator, y - size);
numberIndicator.numberIndicator.setText(value + "");
}
invalidate();
}
}
class NumberIndicator extends Dialog {
Indicator indicator;
TextView numberIndicator;
public NumberIndicator(Context context) {
super(context, android.R.style.Theme_Translucent);
}
#Override
public void dismiss() {
super.dismiss();
indicator.y = 0;
indicator.size = 0;
indicator.animate = true;
}
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.number_indicator_spinner);
setCanceledOnTouchOutside(false);
RelativeLayout content = (RelativeLayout) this
.findViewById(R.id.number_indicator_spinner_content);
indicator = new Indicator(this.getContext());
content.addView(indicator);
numberIndicator = new TextView(getContext());
numberIndicator.setTextColor(Color.WHITE);
numberIndicator.setGravity(Gravity.CENTER);
content.addView(numberIndicator);
indicator.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
}
}
}
Here is my source code.
/*
* This code is a modification of the Android LunarLander example.
*/
package net.simplifiedcoding.detectoutgoingcalls.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import net.simplifiedcoding.detectoutgoingcalls.R;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* View that draws, takes keystrokes, etc. for a simple LunarLander game.
* <p/>
* Has a mode which RUNNING, PAUSED, etc. draw() renders the
* ship, and does an invalidate() to prompt another draw() as soon as possible
* by the system.
*/
public class RotaryDialerView extends View {
private float rotorAngle = 0F;
private final Drawable rotorDrawable;
private final int r1 = 50;
private final int r2 = 160;
private double lastFi;
private int startN;
public MediaPlayer mPlayer;
private int width;
private int height;
private boolean soundRotating;
android.media.MediaPlayer.OnCompletionListener soundListener;
private boolean playSound;
MainActivity activity = new MainActivity();
public RotaryDialerView(Context context) {
this(context, null);
soundListener = new android.media.MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaplayer) {
stop();
}
};
}
public RotaryDialerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RotaryDialerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
playSound = false;
startN = -1;
soundRotating = false;
rotorDrawable = context.getResources().getDrawable(R.drawable.dialer);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int availableWidth = getRight() - getLeft();
int availableHeight = getBottom() - getTop();
int x = availableWidth / 2;
int y = availableHeight / 2;
canvas.save();
rotorDrawable.setBounds(0, 0, rotorDrawable.getIntrinsicWidth(),
rotorDrawable.getIntrinsicHeight());
if (rotorAngle != 0) {
canvas.rotate(rotorAngle, x, y);
}
rotorDrawable.draw(canvas);
canvas.restore();
}
protected void onMeasure(int i, int j) {
height = android.view.View.MeasureSpec.getSize(j);
width = android.view.View.MeasureSpec.getSize(i);
setMeasuredDimension(width, height);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
final float x0 = width / 2;
final float y0 = height / 2;
float x1 = event.getX();
float y1 = event.getY();
float x = x0 - x1;
float y = y0 - y1;
double r = Math.sqrt(x * x + y * y);
double sinfi = y / r;
double fi = Math.toDegrees(Math.asin(sinfi));
if (x1 > x0 && y0 > y1) {
fi = 180D - fi;
} else if (x1 > x0 && y1 > y0) {
fi = 180D - fi;
} else if (x0 > x1 && y1 > y0) {
fi += 360D;
}
boolean isComplete = false;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Log.e("MotionEvent.ACTION_MOVE", "" + MotionEvent.ACTION_MOVE);
if (r > r1 && r < r2) {
if (!soundRotating) {
soundRotating = true;
playSound(startN);
}
final float angle2 = rotorAngle % 360;
int number2 = Math.round(angle2 - 20) / 30;
rotorAngle += Math.abs(fi - lastFi) + 0.25f;
rotorAngle %= 360F;
lastFi = fi;
if (startN >= 10 && !isComplete) {
isComplete = true;
}
// if (number2 < startN || startN == 0 && !isComplete) {
invalidate();
//}
return false;
}
case MotionEvent.ACTION_DOWN:
// playMusic();
// mPlayer2.pause();
calculateStartN(rotorAngle);
rotorAngle = 0F;
lastFi = fi;
return true;
// }
//return false;
case MotionEvent.ACTION_UP:
//mPlayer2.pause();
soundRotating = false;
final float angle = rotorAngle % 360;
int number = Math.round(angle - 20) / 30;
playSound_2(number);
final float fl22 = Math.round(angle - 20) - number * 30;
Log.e("angle", "" + fl22);
if (number > 0) {
if (number == 10) {
number = 0;
}
// if (fl2 < 8.0 && fl2 > 4.0) {
fireDialListenerEvent(number);
//return true;
//}
}
rotorAngle = 0F;
post(new Runnable() {
public void run() {
float fromDegrees = angle;
Animation anim = new RotateAnimation(fromDegrees, 0, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F);
anim.setInterpolator(AnimationUtils.loadInterpolator(getContext(), android.R.anim.decelerate_interpolator));
anim.setAnimationListener(animListener);
anim.setDuration((long) (angle * 5F));
startAnimation(anim);
// playSound();
// angle = 00;//x0;
}
});
startN = -1;
isComplete = false;
return true;
default:
break;
}
return super.onTouchEvent(event);
}
public interface DialListener {
void onDial(int number);
}
private final List<DialListener> dialListeners = new ArrayList<DialListener>();
public void addDialListener(DialListener listener) {
dialListeners.add(listener);
}
public void removeDialListener(DialListener listener) {
dialListeners.remove(listener);
}
private void fireDialListenerEvent(int number) {
for (DialListener listener : dialListeners) {
listener.onDial(number);
Log.e("position ", "Reached");
}
}
private android.view.animation.Animation.AnimationListener animListener = new android.view.animation.Animation.AnimationListener() {
public void onAnimationEnd(Animation animation) {
activity.stopVibrate();
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
};
public void playSound(int n) {
try {
Log.e("n value is", "" + n);
boolean mStartPlaying = true;
if (mStartPlaying == true) {
mPlayer = new MediaPlayer();
Uri uri = Uri.parse("android.resource://net.simplifiedcoding.detectoutgoingcalls/" + activity.SOUNDS_R[n]);
mPlayer.setOnCompletionListener(soundListener);
mPlayer.setDataSource(getContext(), uri);
mPlayer.prepare();
mPlayer.setLooping(false);
mPlayer.start();
} else {
// stopPlaying();
//rePlay.setText("Replay");
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
mStartPlaying = !mStartPlaying;
} catch (IOException e) {
Log.e("ERR", "prepare() failed");
}
}
public void playSound_2(int n) {
try {
boolean mStartPlaying = true;
if (mStartPlaying == true) {
mPlayer = new MediaPlayer();
Uri uri = Uri.parse("android.resource://net.simplifiedcoding.detectoutgoingcalls/" + activity.SOUNDS_S[n]);
mPlayer.setOnCompletionListener(soundListener);
mPlayer.setDataSource(getContext(), uri);
mPlayer.prepare();
mPlayer.setLooping(false);
mPlayer.start();
} else {
// stopPlaying();
//rePlay.setText("Replay");
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
mStartPlaying = !mStartPlaying;
} catch (IOException e) {
Log.e("ERR", "prepare() failed");
}
}
public void stop() {
try {
mPlayer.release();
mPlayer.stop();
return;
}
// Misplaced declaration of an exception variable
catch (Exception mediaplayer) {
return;
}
}
private void calculateStartN(double d) {
if (d >= 0.0D && d < 30D) {
startN = 5;
} else {
if (d >= 30D && d < 60D) {
startN = 4;
return;
}
if (d >= 60D && d < 90D) {
startN = 3;
return;
}
if (d >= 90D && d < 120D) {
startN = 2;
return;
}
if (d >= 120D && d <= 150D) {
startN = 1;
return;
}
if (d >= 210D && d < 240D) {
startN = 0;
return;
}
if (d >= 240D && d < 270D) {
startN = 9;
return;
}
if (d >= 270D && d < 300D) {
startN = 8;
return;
}
if (d >= 300D && d < 330D) {
startN = 7;
return;
}
if (d >= 330D && d <= 360D) {
startN = 6;
return;
}
}
}
}
The problem is when i rotate the dialer number it is not stooped when it reach the point.it rotate contentiously with out end.
here is the sample source code
http://www.ssaurel.com/blog/how-to-create-a-rotary-dialer-application-for-android/
every thing is perfect but the only issue is rotation is not stoped when it reach the end
I am using MUPDF Library and i added features for manual zoom in, zoom out , rating, setting brightness. Now i am doing with long press the highlighted text and i have to show the meaning from my database. I am trying to do with two things one is clipboard or emulateShiftHeld the below feature is for only android ICS and JellyBean. Can any body suggest on whether any one thing will work for this feature what i am trying. Because on Long Press i can't able to capture the text. Suggestions will be helpful.
This id my MUPDF Activity:
public void createUI(Bundle savedInstanceState) {
if (core == null)
return;
// Now create the UI.
// First create the document view making use of the ReaderView's internal
// gesture recognition
mDocView = new ReaderView(this) {
private boolean showButtonsDisabled;
public void onLongPress(MotionEvent e) {
selectAndCopyText();
//mDocView.getSelectedItem();
//SelectText(mDocView);
/*emulateShiftHeld(layout);
clipboard =
(ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(clipboard.getText().toString());
//layout.findAll(clipboard.getText().toString());
//ClipMan.setPrimaryClip(clipboard);
//String s = (String) clipboard.getText();
//System.out.println("fsfasd"+ s);
CharSequence pasteData="";
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
pasteData = item.getText();
System.out.println("fsf"+pasteData);*/
//ClipData data = ClipData.newPlainText("", "");
///System.out.println("sdf" + data);
//copyClipboard();
}
#SuppressWarnings("deprecation")
public void selectAndCopyText() {
try {
Method m = WebView.class.getMethod("emulateShiftHeld", Boolean.TYPE);
m.invoke(mDocView, false);
} catch (Exception e) {
e.printStackTrace();
// fallback
KeyEvent shiftPressEvent = new KeyEvent(0,0,
KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_SHIFT_LEFT,0,0);
shiftPressEvent.dispatch(this);
}
}
public void startTextSelection() {
try {
WebView.class.getMethod("selectText").invoke(this);
} catch (Exception e) {
try {
WebView.class.getMethod("emulateShiftHeld").invoke(this);
} catch (Exception e1) {
KeyEvent shiftPressEvent = new KeyEvent(0, 0,
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0);
shiftPressEvent.dispatch(this);
Toast.makeText(getContext(), R.string.app_name, Toast.LENGTH_LONG).show();
}
}
}
// Stick the document view and the buttons overlay into a parent view
//Embedding my reader view to webview
layout = new WebView(this);
layout.addView(mDocView);
layout.addView(mButtonsView);
layout.setBackgroundResource(R.drawable.tiled_background);
//layout.setBackgroundResource(R.color.canvas);
setContentView(layout);
}
This is my Reader View:
public class ReaderView extends AdapterView<Adapter>
implements GestureDetector.OnGestureListener,
ScaleGestureDetector.OnScaleGestureListener,
Runnable {
private static final int MOVING_DIAGONALLY = 0;
private static final int MOVING_LEFT = 1;
private static final int MOVING_RIGHT = 2;
private static final int MOVING_UP = 3;
private static final int MOVING_DOWN = 4;
private static final int FLING_MARGIN = 100;
private static final int GAP = 20;
private static final int SCROLL_SPEED = 2;
private static final float MIN_SCALE = 1.0f;
private static final float MAX_SCALE = 5.0f;
private Adapter mAdapter;
private int mCurrent; // Adapter's index for the current view
private boolean mResetLayout;
private final SparseArray<View>
mChildViews = new SparseArray<View>(3);
// Shadows the children of the adapter view
// but with more sensible indexing
private final LinkedList<View>
mViewCache = new LinkedList<View>();
private boolean mUserInteracting; // Whether the user is interacting
private boolean mScaling; // Whether the user is currently pinch zooming
private float mScale = 1.0f;
private int mXScroll; // Scroll amounts recorded from events.
private int mYScroll; // and then accounted for in onLayout
private final GestureDetector
mGestureDetector;
private final ScaleGestureDetector
mScaleGestureDetector;
private final Scroller mScroller;
private int mScrollerLastX;
private int mScrollerLastY;
private boolean mScrollDisabled;
public ReaderView(Context context) {
super(context);
mGestureDetector = new GestureDetector(this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
mScroller = new Scroller(context);
}
public ReaderView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
mScroller = new Scroller(context);
}
public ReaderView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mGestureDetector = new GestureDetector(this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
mScroller = new Scroller(context);
}
public int getDisplayedViewIndex(ToggleButton bookmark_page, String index_from) {
if (index_from.equals("bookmark_button")) { System.out.println("View_if" + index_from);
bookmark_page.setBackgroundResource(R.drawable.top3hover);
} else { System.out.println("View_else" + index_from);
bookmark_page.setBackgroundResource(R.drawable.top3);
}
return mCurrent;
}
public void setDisplayedViewIndex(int i) {
if (0 <= i && i < mAdapter.getCount()) {
mCurrent = i;
onMoveToChild(i);
mResetLayout = true;
requestLayout();
}
}
public void moveToNext() {
View v = mChildViews.get(mCurrent+1);
if (v != null)
slideViewOntoScreen(v);
}
public void moveToPrevious() {
View v = mChildViews.get(mCurrent-1);
if (v != null)
slideViewOntoScreen(v);
}
public void resetupChildren() {
for (int i = 0; i < mChildViews.size(); i++)
onChildSetup(mChildViews.keyAt(i), mChildViews.valueAt(i));
}
protected void onChildSetup(int i, View v) {}
protected void onMoveToChild(int i) {}
protected void onSettle(View v) {};
protected void onUnsettle(View v) {};
protected void onNotInUse(View v) {};
public View getDisplayedView() {
return mChildViews.get(mCurrent);
}
public void run() {
if (!mScroller.isFinished()) {
mScroller.computeScrollOffset();
int x = mScroller.getCurrX();
int y = mScroller.getCurrY();
mXScroll += x - mScrollerLastX;
mYScroll += y - mScrollerLastY;
mScrollerLastX = x;
mScrollerLastY = y;
requestLayout();
post(this);
}
else if (!mUserInteracting) {
// End of an inertial scroll and the user is not interacting.
// The layout is stable
View v = mChildViews.get(mCurrent);
postSettle(v);
}
}
public boolean onDown(MotionEvent arg0) {
mScroller.forceFinished(true);
return true;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (mScrollDisabled)
return true;
View v = mChildViews.get(mCurrent);
if (v != null) {
Rect bounds = getScrollBounds(v);
switch(directionOfTravel(velocityX, velocityY)) {
case MOVING_LEFT:
if (bounds.left >= 0) {
// Fling off to the left bring next view onto screen
View vl = mChildViews.get(mCurrent+1);
if (vl != null) {
slideViewOntoScreen(vl);
return true;
}
}
break;
case MOVING_RIGHT:
if (bounds.right <= 0) {
// Fling off to the right bring previous view onto screen
View vr = mChildViews.get(mCurrent-1);
if (vr != null) {
slideViewOntoScreen(vr);
return true;
}
}
break;
}
mScrollerLastX = mScrollerLastY = 0;
// If the page has been dragged out of bounds then we want to spring back
// nicely. fling jumps back into bounds instantly, so we don't want to use
// fling in that case. On the other hand, we don't want to forgo a fling
// just because of a slightly off-angle drag taking us out of bounds other
// than in the direction of the drag, so we test for out of bounds only
// in the direction of travel.
//
// Also don't fling if out of bounds in any direction by more than fling
// margin
Rect expandedBounds = new Rect(bounds);
expandedBounds.inset(-FLING_MARGIN, -FLING_MARGIN);
if(withinBoundsInDirectionOfTravel(bounds, velocityX, velocityY)
&& expandedBounds.contains(0, 0)) {
mScroller.fling(0, 0, (int)velocityX, (int)velocityY, bounds.left, bounds.right, bounds.top, bounds.bottom);
post(this);
}
}
return true;
}
public void onLongPress(MotionEvent e) {
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
if (!mScrollDisabled) {
mXScroll -= distanceX;
mYScroll -= distanceY;
requestLayout();
}
return true;
}
public void onShowPress(MotionEvent e) {
}
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public boolean onScale(ScaleGestureDetector detector) {
float previousScale = mScale;
mScale = Math.min(Math.max(mScale * detector.getScaleFactor(), MIN_SCALE), MAX_SCALE);
float factor = mScale/previousScale;
View v = mChildViews.get(mCurrent);
if (v != null) {
// Work out the focus point relative to the view top left
int viewFocusX = (int)detector.getFocusX() - (v.getLeft() + mXScroll);
int viewFocusY = (int)detector.getFocusY() - (v.getTop() + mYScroll);
// Scroll to maintain the focus point
mXScroll += viewFocusX - viewFocusX * factor;
mYScroll += viewFocusY - viewFocusY * factor;
requestLayout();
}
return true;
}
public boolean onScaleBegin(ScaleGestureDetector detector) {
mScaling = true;
// Ignore any scroll amounts yet to be accounted for: the
// screen is not showing the effect of them, so they can
// only confuse the user
mXScroll = mYScroll = 0;
// Avoid jump at end of scaling by disabling scrolling
// until the next start of gesture
mScrollDisabled = true;
return true;
}
public void onScaleEnd(ScaleGestureDetector detector) {
mScaling = false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
//mScaleGestureDetector.onTouchEvent(event);
if (!mScaling)
mGestureDetector.onTouchEvent(event);
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mUserInteracting = true;
}
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
mScrollDisabled = false;
mUserInteracting = false;
View v = mChildViews.get(mCurrent);
if (v != null) {
if (mScroller.isFinished()) {
// If, at the end of user interaction, there is no
// current inertial scroll in operation then animate
// the view onto screen if necessary
slideViewOntoScreen(v);
}
if (mScroller.isFinished()) {
// If still there is no inertial scroll in operation
// then the layout is stable
postSettle(v);
}
}
}
requestLayout();
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int n = getChildCount();
for (int i = 0; i < n; i++)
measureView(getChildAt(i));
}
#Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
View cv = mChildViews.get(mCurrent);
Point cvOffset;
if (!mResetLayout) {
// Move to next or previous if current is sufficiently off center
if (cv != null) {
cvOffset = subScreenSizeOffset(cv);
// cv.getRight() may be out of date with the current scale
// so add left to the measured width for the correct position
if (cv.getLeft() + cv.getMeasuredWidth() + cvOffset.x + GAP/2 + mXScroll < getWidth()/2 && mCurrent + 1 < mAdapter.getCount()) {
postUnsettle(cv);
// post to invoke test for end of animation
// where we must set hq area for the new current view
post(this);
mCurrent++;
onMoveToChild(mCurrent);
}
if (cv.getLeft() - cvOffset.x - GAP/2 + mXScroll >= getWidth()/2 && mCurrent > 0) {
postUnsettle(cv);
// post to invoke test for end of animation
// where we must set hq area for the new current view
post(this);
mCurrent--;
onMoveToChild(mCurrent);
}
}
// Remove not needed children and hold them for reuse
int numChildren = mChildViews.size();
int childIndices[] = new int[numChildren];
for (int i = 0; i < numChildren; i++)
childIndices[i] = mChildViews.keyAt(i);
for (int i = 0; i < numChildren; i++) {
int ai = childIndices[i];
if (ai < mCurrent - 1 || ai > mCurrent + 1) {
View v = mChildViews.get(ai);
onNotInUse(v);
mViewCache.add(v);
removeViewInLayout(v);
mChildViews.remove(ai);
}
}
} else {
mResetLayout = false;
mXScroll = mYScroll = 0;
// Remove all children and hold them for reuse
int numChildren = mChildViews.size();
for (int i = 0; i < numChildren; i++) {
View v = mChildViews.valueAt(i);
onNotInUse(v);
mViewCache.add(v);
removeViewInLayout(v);
}
mChildViews.clear();
// post to ensure generation of hq area
post(this);
}
// Ensure current view is present
int cvLeft, cvRight, cvTop, cvBottom;
boolean notPresent = (mChildViews.get(mCurrent) == null);
cv = getOrCreateChild(mCurrent);
// When the view is sub-screen-size in either dimension we
// offset it to center within the screen area, and to keep
// the views spaced out
cvOffset = subScreenSizeOffset(cv);
if (notPresent) {
//Main item not already present. Just place it top left
cvLeft = cvOffset.x;
cvTop = cvOffset.y;
} else {
// Main item already present. Adjust by scroll offsets
cvLeft = cv.getLeft() + mXScroll;
cvTop = cv.getTop() + mYScroll;
}
// Scroll values have been accounted for
mXScroll = mYScroll = 0;
cvRight = cvLeft + cv.getMeasuredWidth();
cvBottom = cvTop + cv.getMeasuredHeight();
if (!mUserInteracting && mScroller.isFinished()) {
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
cvRight += corr.x;
cvLeft += corr.x;
cvTop += corr.y;
cvBottom += corr.y;
} else if (cv.getMeasuredHeight() <= getHeight()) {
// When the current view is as small as the screen in height, clamp
// it vertically
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
cvTop += corr.y;
cvBottom += corr.y;
}
cv.layout(cvLeft, cvTop, cvRight, cvBottom);
if (mCurrent > 0) {
View lv = getOrCreateChild(mCurrent - 1);
Point leftOffset = subScreenSizeOffset(lv);
int gap = leftOffset.x + GAP + cvOffset.x;
lv.layout(cvLeft - lv.getMeasuredWidth() - gap,
(cvBottom + cvTop - lv.getMeasuredHeight())/2,
cvLeft - gap,
(cvBottom + cvTop + lv.getMeasuredHeight())/2);
}
if (mCurrent + 1 < mAdapter.getCount()) {
View rv = getOrCreateChild(mCurrent + 1);
Point rightOffset = subScreenSizeOffset(rv);
int gap = cvOffset.x + GAP + rightOffset.x;
rv.layout(cvRight + gap,
(cvBottom + cvTop - rv.getMeasuredHeight())/2,
cvRight + rv.getMeasuredWidth() + gap,
(cvBottom + cvTop + rv.getMeasuredHeight())/2);
}
invalidate();
}
#Override
public Adapter getAdapter() {
return mAdapter;
}
#Override
public View getSelectedView() {
throw new UnsupportedOperationException("Not supported");
}
#Override
public void setAdapter(Adapter adapter) {
mAdapter = adapter;
mChildViews.clear();
removeAllViewsInLayout();
requestLayout();
}
#Override
public void setSelection(int arg0) {
throw new UnsupportedOperationException("Not supported");
}
private View getCached() {
if (mViewCache.size() == 0)
return null;
else
return mViewCache.removeFirst();
}
private View getOrCreateChild(int i) {
View v = mChildViews.get(i);
if (v == null) {
v = mAdapter.getView(i, getCached(), this);
addAndMeasureChild(i, v);
}
onChildSetup(i, v);
return v;
}
private void addAndMeasureChild(int i, View v) {
LayoutParams params = v.getLayoutParams();
if (params == null) {
params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
addViewInLayout(v, 0, params, true);
mChildViews.append(i, v); // Record the view against it's adapter index
measureView(v);
}
private void measureView(View v) {
// See what size the view wants to be
v.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// Work out a scale that will fit it to this view
float scale = Math.min((float)getWidth()/(float)v.getMeasuredWidth(),
(float)getHeight()/(float)v.getMeasuredHeight());
// Use the fitting values scaled by our current scale factor
v.measure(View.MeasureSpec.EXACTLY | (int)(v.getMeasuredWidth()*scale*mScale),
View.MeasureSpec.EXACTLY | (int)(v.getMeasuredHeight()*scale*mScale));
}
private Rect getScrollBounds(int left, int top, int right, int bottom) {
int xmin = getWidth() - right;
int xmax = -left;
int ymin = getHeight() - bottom;
int ymax = -top;
// In either dimension, if view smaller than screen then
// constrain it to be central
if (xmin > xmax) xmin = xmax = (xmin + xmax)/2;
if (ymin > ymax) ymin = ymax = (ymin + ymax)/2;
return new Rect(xmin, ymin, xmax, ymax);
}
private Rect getScrollBounds(View v) {
// There can be scroll amounts not yet accounted for in
// onLayout, so add mXScroll and mYScroll to the current
// positions when calculating the bounds.
return getScrollBounds(v.getLeft() + mXScroll,
v.getTop() + mYScroll,
v.getLeft() + v.getMeasuredWidth() + mXScroll,
v.getTop() + v.getMeasuredHeight() + mYScroll);
}
private Point getCorrection(Rect bounds) {
return new Point(Math.min(Math.max(0,bounds.left),bounds.right),
Math.min(Math.max(0,bounds.top),bounds.bottom));
}
private void postSettle(final View v) {
// onSettle and onUnsettle are posted so that the calls
// wont be executed until after the system has performed
// layout.
post (new Runnable() {
public void run () {
onSettle(v);
}
});
}
private void postUnsettle(final View v) {
post (new Runnable() {
public void run () {
onUnsettle(v);
}
});
}
private void slideViewOntoScreen(View v) {
Point corr = getCorrection(getScrollBounds(v));
if (corr.x != 0 || corr.y != 0) {
mScrollerLastX = mScrollerLastY = 0;
mScroller.startScroll(0, 0, corr.x, corr.y, 400);
post(this);
}
}
private Point subScreenSizeOffset(View v) {
return new Point(Math.max((getWidth() - v.getMeasuredWidth())/2, 0),
Math.max((getHeight() - v.getMeasuredHeight())/2, 0));
}
private static int directionOfTravel(float vx, float vy) {
if (Math.abs(vx) > 2 * Math.abs(vy))
return (vx > 0) ? MOVING_RIGHT : MOVING_LEFT;
else if (Math.abs(vy) > 2 * Math.abs(vx))
return (vy > 0) ? MOVING_DOWN : MOVING_UP;
else
return MOVING_DIAGONALLY;
}
private static boolean withinBoundsInDirectionOfTravel(Rect bounds, float vx, float vy) {
switch (directionOfTravel(vx, vy)) {
case MOVING_DIAGONALLY: return bounds.contains(0, 0);
case MOVING_LEFT: return bounds.left <= 0;
case MOVING_RIGHT: return bounds.right >= 0;
case MOVING_UP: return bounds.top <= 0;
case MOVING_DOWN: return bounds.bottom >= 0;
default: throw new NoSuchElementException();
}
}
}
In Reader Class, make localbroadcast and implement it in your main Activity
public void onLongPress(MotionEvent e) {
Intent next = new Intent(StringConstant.SEARCH_WORD);
next.putExtra(StringConstant.DOUBLE_TAP_PDF, "true");
LocalBroadcastManager.getInstance(mContext).sendBroadcast(next);
}
This is your broadcast reciever
private BroadcastReceiver mPdfDoubleClickedReciever = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
Log.e("", "mPdfDoubleClickedReciever called");
hideEditedNotes();
MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
boolean success = false;
if (pageView != null)
success = pageView.copySelection();
mTopBarMode = TopBarMode.Main;
// showInfo(success ?
// getString(R.string.copied_to_clipboard)
// : getString(R.string.no_text_selected));
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
selectedClipboardText = "";
selectedClipboardText = (String) clipboard.getText();
// Do task here
}
}
};