I am creating a soundboard Android application in order to gain more of an understanding of what goes on under the hood of an application.
Currently have three seekbars in an activity called ChangeSounds. They control volume, panning and playback speed. I have coded a java file called SoundManager that handles these parameters. I am at the stage of linking the functionality of the soundManager to the ChangeSounds activity but I don't know how I should go about doing it. Should I use an intent? Or should I use a broadcast receiver? Any help would be greatly appreciated.
ChangeSounds.java
package com.example.beatpadmaker;
// Importing necessary libraries
import android.app.Activity;
import android.os.Bundle;
public class ChangeSounds extends Activity {
// sets the layout to changesounds
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.changesounds);
}
changesounds.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/metalbackground"
android:orientation="vertical" >
<!-- Creates the settings text -->
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/titlesettings"
android:textColor="#FFFFFF"
android:textSize="30sp" >
</TextView>
<!-- Creates the volume text -->
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/volumebar"
android:textColor="#FFFFFF" >
</TextView>
<!-- Creates the seekbar for volume -->
<SeekBar
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="#+id/VolBar1"
android:max="100"
android:progress="100">
</SeekBar>
<!-- Creates the balance text -->
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/balance"
android:textColor="#FFFFFF" >
</TextView>
<!-- Creates the seekbar for audio balance -->
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="200"
android:id="#+id/BalBar"
android:progress="100">
</SeekBar>
<!-- Creates the speed text -->
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/speed"
android:textColor="#FFFFFF" >
</TextView>
<!-- Creates the seekbar for speed -->
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/SpeedBar"
android:max="200"
android:progress="100">
</SeekBar>
</LinearLayout>
SoundManager.java
package com.example.beatpadmaker;
//Importing necessary libraries
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
public class SoundManager {
//Initialising all variables
private Context pContext;
private SoundPool sndPool;
private float rate = 1.0f;
private float masterVolume = 1.0f;
private float leftVolume = 1.0f;
private float rightVolume = 1.0f;
private float balance = 0.5f;
// Constructor that is used to setup the audio manager and store the application context
public SoundManager(Context appContext)
{
sndPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100);
pContext = appContext;
}
// Load up a sound and return the id
public int load(int sound_id)
{
return sndPool.load(pContext, sound_id, 1);
}
// Play a sound
public void play(int sound_id)
{
sndPool.play(sound_id, leftVolume, rightVolume, 1, 0, rate);
}
// Set volume values based on existing volume value
public void setVolume(float vol)
{
masterVolume = vol;
if(balance < 1.0f)
{
leftVolume = masterVolume;
rightVolume = masterVolume * balance;
}
else
{
rightVolume = masterVolume;
leftVolume = masterVolume * ( 2.0f - balance );
}
}
// Determine the speed of audio playback
public void setSpeed(float speed)
{
rate = speed;
// Speed of zero is invalid
if(rate < 0.01f)
rate = 0.01f;
// Speed has a maximum of 2.0
if(rate > 2.0f)
rate = 2.0f;
}
// Recalculate volume levels
public void setBalance(float balVal)
{
balance = balVal;
setVolume(masterVolume);
}
// Releases the soundpool's contents
public void unloadAll()
{
sndPool.release();
}
}
MainMenu.java
package com.example.beatpadmaker;
//Importing necessary libraries
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MainMenu extends Activity {
//Initializing all variables as well as a tag string for testing my life cycle in logcat
private static final String TAG= MainMenu.class.getSimpleName();
SoundManager snd;
int sound1, sound2, sound3, sound4, sound5, sound6, sound7, sound8, sound9, sound10, sound11, sound12;
OnSeekBarChangeListener barChange;
OnClickListener buttonClick;
//Creating the layout
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
Log.d(TAG, "onCreate() called!");
// Create an instance of our sound manger
snd = new SoundManager(getApplicationContext());
// Set volume rocker mode to media volume
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the samples from res/raw as oggs
sound1 = snd.load(R.raw.sound1);
sound2 = snd.load(R.raw.sound2);
sound3 = snd.load(R.raw.sound3);
sound4 = snd.load(R.raw.sound4);
sound5 = snd.load(R.raw.sound5);
sound6 = snd.load(R.raw.sound6);
sound7 = snd.load(R.raw.sound7);
sound8 = snd.load(R.raw.sound8);
sound9 = snd.load(R.raw.sound9);
sound10 = snd.load(R.raw.sound10);
sound11 = snd.load(R.raw.sound11);
sound12 = snd.load(R.raw.sound12);
// Create a seek bar handler
barChange = new OnSeekBarChangeListener()
{
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
//Creating the three cases for the different seekbars to get the progress of volume, balance and speed
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
switch (seekBar.getId())
{
case R.id.VolBar1:
snd.setVolume((float)progress/100.0f);
break;
case R.id.BalBar:
snd.setBalance((float)progress/100.0f);
break;
case R.id.SpeedBar:
snd.setSpeed((float)progress/100.0f);
break;
}
}
};
}
// Button listener assigned in XML layout
public void clickHandler(View v)
{
int id = v.getId();
// Use the button id to determine which sample should be played
switch (id)
{
case R.id.button1:
snd.play(sound1);
break;
case R.id.button2:
snd.play(sound2);
break;
case R.id.button3:
snd.play(sound3);
break;
case R.id.button4:
snd.play(sound4);
break;
case R.id.button5:
snd.play(sound5);
break;
case R.id.button6:
snd.play(sound6);
break;
case R.id.button7:
snd.play(sound7);
break;
case R.id.button8:
snd.play(sound8);
break;
case R.id.button9:
snd.play(sound9);
break;
case R.id.button10:
snd.play(sound10);
break;
case R.id.button11:
snd.play(sound11);
break;
case R.id.button12:
snd.play(sound12);
break;
}
}
in onCreate(), get a reference to each seekbar using
SeekBar bar = (SeekBar) findViewById(R.id.volume);
Then set the listener on it.
bar.setOnSeekBarChangeListener(barChangeListener);
Make sure if you do this way you define the listener.
private OnSeekBarChangeListener barChangeListener = new OnSeekBarChangeListener() {
// implement abstract methods
}
Related
I am trying to make a program in Android Studio using java, where I can determine the RGB values at the point where the user clicked on the image. The code is working so far, but it gives wrong RGB values as output. They also seem to vary, based on the location where I click, even if the color that should be put out is the same. My guess is, that there is something up with the Bitmap, that I don't know about.
My MainActivity :
package com.example.fitme;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int evX = (int) ev.getX();
final int evY = (int) ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN :
break;
case MotionEvent.ACTION_UP :
ImageView img = (ImageView) findViewById (R.id.body_front_map);
img.setDrawingCacheEnabled(true);
Bitmap imgbmp = Bitmap.createBitmap(img.getDrawingCache());
img.setDrawingCacheEnabled(false);
int pxl = imgbmp.getPixel(evX, evY);
int redComponent = Color.red(pxl);
int greenComponent = Color.green(pxl);
int blueComponent = Color.blue(pxl);
Toast.makeText(MainActivity.this,"RED: "+redComponent+" GREEN: "+greenComponent+" BLUE: "+blueComponent, Toast.LENGTH_SHORT).show();
break;
}
return false;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="#+id/body_front_map"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:background="#drawable/body_front_map"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The Image I am trying to use
Hi i'm a beginner in android app development.
I need help making my app. so my app is a simple Timer with progress bar which works fine.
Now i need to make that "progress bar's" to draw over other apps even if the app is minimized or closed until the timer expires.
So for this I tried many things in many ways like i used Window Manager and other things in a service class, i even separated progress bar into different layout.
help me with code. the following contains code which works fine within app.
1)Main Activity.java
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private long timeCountInMilliSeconds = 1 * 60000;
private enum TimerStatus {
STARTED,
STOPPED
}
private TimerStatus timerStatus = TimerStatus.STOPPED;
private ProgressBar progressBar;
private ProgressBar progressBar1;
private EditText editTextMinute;
private TextView textViewTime;
private ImageView imageViewReset;
private ImageView imageViewStartStop;
private CountDownTimer countDownTimer;
private ObjectAnimator smoothAnimation;
private ObjectAnimator smoothAnimation1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// method call to initialize the views
initViews();
// method call to initialize the listeners
initListeners();
}
/**
* method to initialize the views
*/
private void initViews() {
progressBar = findViewById(R.id.progress_bar);
progressBar1 = findViewById(R.id.progress_bar1);
editTextMinute = findViewById(R.id.editTextMinute);
textViewTime = findViewById(R.id.textViewTime);
imageViewReset = findViewById(R.id.imageViewReset);
imageViewStartStop = findViewById(R.id.imageViewStartStop);
}
/**
* method to initialize the click listeners
*/
private void initListeners() {
imageViewReset.setOnClickListener(this);
imageViewStartStop.setOnClickListener(this);
}
/**
* implemented method to listen clicks
*
* #param view
*/
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imageViewReset:
reset();
break;
case R.id.imageViewStartStop:
startStop();
break;
}
}
/**
* method to reset count down timer
*/
private void reset() {
stopCountDownTimer();
startCountDownTimer();
}
/**
* method to start and stop count down timer
*/
private void startStop() {
if (timerStatus == TimerStatus.STOPPED) {
// call to initialize the timer values
setTimerValues();
// call to initialize the progress bar values
setProgressBarValues();
// showing the reset icon
imageViewReset.setVisibility(View.VISIBLE);
// changing play icon to stop icon
imageViewStartStop.setImageResource(R.drawable.icon_stop);
// making edit text not editable
editTextMinute.setEnabled(false);
// changing the timer status to started
timerStatus = TimerStatus.STARTED;
// call to start the count down timer
startCountDownTimer();
} else {
// hiding the reset icon
imageViewReset.setVisibility(View.GONE);
// changing stop icon to start icon
imageViewStartStop.setImageResource(R.drawable.icon_start);
// making edit text editable
editTextMinute.setEnabled(true);
// changing the timer status to stopped
timerStatus = TimerStatus.STOPPED;
stopCountDownTimer();
}
}
/**
* method to initialize the values for count down timer
*/
private void setTimerValues() {
int time = 0;
if (!editTextMinute.getText().toString().isEmpty()) {
// fetching value from edit text and type cast to integer
time = Integer.parseInt(editTextMinute.getText().toString().trim());
} else {
// toast message to fill edit text
Toast.makeText(getApplicationContext(), getString(R.string.message_minutes), Toast.LENGTH_LONG).show();
}
// assigning values after converting to milliseconds
timeCountInMilliSeconds = time * 1000;
}
/**
* method to start count down timer
*/
private void startCountDownTimer() {
//left side Progress Bar
smoothAnimation = ObjectAnimator.ofInt(progressBar, "progress", progressBar.getProgress(), progressBar.getMax());
smoothAnimation.setDuration(5);
smoothAnimation.setInterpolator(new AccelerateInterpolator());
//right side Progress Bar
smoothAnimation1 = ObjectAnimator.ofInt(progressBar, "progress", progressBar1.getProgress(), progressBar1.getMax());
smoothAnimation1.setDuration(5);
smoothAnimation1.setInterpolator(new AccelerateInterpolator());
countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 10) {
#Override
public void onTick(long millisUntilFinished) {
Log.d("TAG", "ON Tick Called "+millisUntilFinished);
textViewTime.setText(hmsTimeFormatter(millisUntilFinished+1000));
progressBar.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
progressBar1.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
}
#Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
// call to initialize the progress bar values
setProgressBarValues();
// hiding the reset icon
imageViewReset.setVisibility(View.GONE);
// changing stop icon to start icon
imageViewStartStop.setImageResource(R.drawable.icon_start);
// making edit text editable
editTextMinute.setEnabled(true);
// changing the timer status to stopped
timerStatus = TimerStatus.STOPPED;
smoothAnimation.end();
}
}.start();
smoothAnimation.start();
countDownTimer.start();
}
/**
* method to stop count down timer
*/
private void stopCountDownTimer() {
countDownTimer.cancel();
}
/**
* method to set circular progress bar values
*/
private void setProgressBarValues() {
progressBar.setMax((int) (timeCountInMilliSeconds / 10));
progressBar.setProgress((int) (timeCountInMilliSeconds / 10));
progressBar1.setMax((int) (timeCountInMilliSeconds / 10));
progressBar1.setProgress((int) (timeCountInMilliSeconds / 10));
}
/**
* method to convert millisecond to time format
*
* #param milliSeconds
* #return HH:mm:ss time formatted string
*/
private String hmsTimeFormatter(long milliSeconds) {
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(milliSeconds),
TimeUnit.MILLISECONDS.toMinutes(milliSeconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSeconds)),
TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));
return hms;
}
}
2)activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBackground">
<ProgressBar
android:id="#+id/progress_bar"
android:animationResolution="6000"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/progressbar_vertical" />
<ProgressBar
android:id="#+id/progress_bar1"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:animationResolution="6000"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/progressbar_vertical" />
<EditText
android:id="#+id/editTextMinute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewTime"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:gravity="center"
android:hint="#string/hint_minute"
android:inputType="number"
android:maxLength="15"
android:maxLines="1"
android:minEms="5"
android:text=""
android:textColor="#color/colorYellow"
android:textColorHint="#color/colorYellow" />
<TextView
android:id="#+id/textViewTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="00:01:00"
android:textColor="#color/colorYellow"
android:textSize="40sp" />
<ImageView
android:id="#+id/imageViewStartStop"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/textViewTime"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:src="#drawable/icon_start" />
<ImageView
android:id="#+id/imageViewReset"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_below="#+id/imageViewStartStop"
android:layout_centerInParent="true"
android:layout_marginTop="30dp"
android:src="#drawable/icon_reset"
tools:visibility="visible"
android:visibility="gone" />
</RelativeLayout>
The following contains some screenshots please take a look.
Timer pic
Timer pic 2
The Above code works
Now i added service code that i am trying
-ProgressBarService.java (In this i don't know which code should i move from main activity to this and HOW??)
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import static android.view.Gravity.END;
public class ProgressBarService extends Service {
private WindowManager mWindowManager;
private View mProgressView;
public ProgressBarService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("InflateParams")
#Override
public void onCreate() {
super.onCreate();
mProgressView = LayoutInflater.from(this).inflate(R.layout.progressbar_view, null);
final WindowManager.LayoutParams paramsProgress = getLayoutParams();
paramsProgress.gravity=END;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if (mWindowManager != null) {
mWindowManager.addView(mProgressView, paramsProgress);
}
}
private WindowManager.LayoutParams getLayoutParams() {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
return params;
}
#Override
public void onDestroy() {
super.onDestroy();
if (mProgressView != null) mWindowManager.removeView(mProgressView);
}
}
-progressbar_view (seperated from activity_main)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="#+id/progress_bar"
android:animationResolution="6000"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:progress="100"
android:progressDrawable="#drawable/progressbar_vertical" />
<!-- <ProgressBar
android:id="#+id/progress_bar1"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:animationResolution="6000"
android:max="100"
android:progress="100"
android:progressDrawable="#drawable/progressbar_vertical" />-->
</RelativeLayout>
Im super new and have slowly been working on an app. ive kinda hit a road block when ive tried to make an image moveable by pressing it and dragging it. I used this as my inital reference.
http://www.devexchanges.info/2015/03/simple-moving-object-with-touch-events.html
But when I do that and run it nothing happens when i press the image to move it around. Heres what my Code looks like. I feel like it is a super simple solution. I dont have any errors in the code according to android studio.
Below is my activity_touch.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_touch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#24d7d4"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.daniel.movebutton.activity_touch">
<ImageView
android:id="#+id/image"
android:layout_width="150dp"
android:layout_height="150dp"
android:contentDescription="#string/app_name"
android:src="#drawable/bunny"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Here is the activity_touch.java
package com.example.daniel.movebutton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class activity_touch extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_touch);
}
}
Then this is my TouchActivity.java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
public class TouchActivity extends Activity {
private ViewGroup mainLayout;
private ImageView image;
private int xDelta;
private int yDelta;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_touch);
mainLayout = (RelativeLayout) findViewById(R.id.activity_touch);
image = (ImageView) findViewById(R.id.image);
image.setOnTouchListener(onTouchListener());
}
private OnTouchListener onTouchListener() {
return new OnTouchListener() {
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouch(View view, MotionEvent event) {
final int x = (int) event.getRawX();
final int y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams)
view.getLayoutParams();
xDelta = x - lParams.leftMargin;
yDelta = y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
Toast.makeText(TouchActivity.this,
"thanks for new location!", Toast.LENGTH_SHORT)
.show();
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = x - xDelta;
layoutParams.topMargin = y - yDelta;
layoutParams.rightMargin = 0;
layoutParams.bottomMargin = 0;
view.setLayoutParams(layoutParams);
break;
}
mainLayout.invalidate();
return true;
}
};
}
}
I really feel like Im just missing something in the activity_touch.java
Any help would be great! Thanks guys!
I use this code
TextView.animate().setDuration(0).scaleX(scale).scaleY(scale).start();
When scale value increase to some point, it make TextView disappear. I dont know why, and how to prevent it?
[Edit] Attach my test code
[test_text_scale.xml] It is Layout xml file for TestTextScale.java
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:orientation="vertical">
<TextView
android:id="#+id/tv_test_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Test" />
<Button
android:id="#+id/bt_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toEndOf="#+id/bt_down"
android:layout_toRightOf="#+id/bt_down"
android:text="Up" />
<Button
android:id="#+id/bt_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="Down" />
</RelativeLayout>
[TestTextScale.java]
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TestTextScale extends AppCompatActivity {
// View
private TextView mTvTestZoom;
private Button mBtUp, mBtDown;
// Model
private int mCurrentScale = 1;
// OnClick listener
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_up : {
upScale();
setText();
} break;
case R.id.bt_down : {
downScale();
setText();
} break;
}
}
};
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_text_scale);
initView();
initEvent();
}
private void initView() {
mTvTestZoom = (TextView) findViewById(R.id.tv_test_scale);
mBtUp = (Button) findViewById(R.id.bt_up);
mBtDown = (Button) findViewById(R.id.bt_down);
}
private void initEvent() {
mBtDown.setOnClickListener(mOnClickListener);
mBtUp.setOnClickListener(mOnClickListener);
}
private void upScale() {
mCurrentScale += 1;
mTvTestZoom.animate().setDuration(0).scaleX(mCurrentScale).scaleY(mCurrentScale).start();
}
private void downScale() {
mCurrentScale -= 1;
mTvTestZoom.animate().setDuration(0).scaleX(mCurrentScale).scaleY(mCurrentScale).start();
}
private void setText() {
mTvTestZoom.setText(mCurrentScale + "");
}
}
This may happen because the textview exceeds the layout bounds of its parent. To overcome this, simple put android:clipChildren="false" in the xml description of the immediate parent of the textview. You may also need to do it for their parents too.
EDIT:
Upon testing the code myself, I found that the textview did disappear with following log message:
E/OpenGLRenderer: Font size too large to fit in cache. width, height = 635, 1028
This is due to a possible issue in the Android Hardware acceleration modules. One of the ways to avoid this is:
mTvTestZoom.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
This works well and the textView does not disappear after a certain size but, since it disables hardware acceleration for the specific textview, it may lose antialiasing.
I am trying to display a different message depending on where an image is dragged.
So far, I have been able to drag and drop an image with motion event. And I have created 3 textviews that are invisible when the app starts (Too High, Perfect, and Too Low).
After the user moves the image, I want to display a different message depending on if it falls within certain y coordinates.
So how do I figure out if the image is within the desired y coordinates and then set the text to be visible if it is within those coordinates?
Here is my code so far:
Main Activity:
package com.example.touchanddragimage;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity implements OnTouchListener {
ImageView arrow;
TextView hightext;
TextView lowtext;
TextView perfecttext;
TextView guide;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrow = (ImageView)findViewById(R.id.arrow);
arrow.setOnTouchListener(this);
hightext = (TextView) findViewById(R.id.high) ;
lowtext = (TextView) findViewById(R.id.low);
perfecttext = (TextView) findViewById(R.id.perfect);
guide = (TextView) findViewById(R.id.textView2);
hightext.setVisibility(View.INVISIBLE);
lowtext.setVisibility(View.INVISIBLE);
perfecttext.setVisibility(View.INVISIBLE);
}
float x,y=0.0f;
boolean moving = false;
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
switch(arg1.getAction()){
case MotionEvent.ACTION_DOWN:
moving=true;
break;
case MotionEvent.ACTION_MOVE:
if(moving){
x=arg1.getRawX()-arrow.getWidth()/2;
y=arg1.getRawY()-arrow.getHeight()*3/2;
arrow.setX(x);
arrow.setY(y);
}
break;
case MotionEvent.ACTION_UP:
moving=false;
break;
}
return true;
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.touchanddragimage.MainActivity" >
<ImageView
android:id="#+id/arrow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView1"
android:layout_marginTop="351dp"
android:src="#drawable/greenarrow" />
<TextView
android:id="#+id/high"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/arrow"
android:layout_below="#+id/textView1"
android:layout_marginRight="99dp"
android:layout_marginTop="56dp"
android:text="#string/high"
android:textSize="24sp"
/>
<TextView
android:id="#+id/perfect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/high"
android:layout_marginTop="131dp"
android:layout_toLeftOf="#+id/low"
android:text="#string/perfect"
android:textSize="24sp" />
<TextView
android:id="#+id/low"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/high"
android:layout_below="#+id/arrow"
android:layout_marginLeft="46dp"
android:layout_marginTop="182dp"
android:text="#string/low"
android:textSize="24sp" />
</RelativeLayout>
In your MotionEvent.ACTION_UP check the value of the y coordinate and if it lies within a desired range then set the visibility of textview e.g
case MotionEvent.ACTION_UP:
moving=false;
if(y < 100){
high.setVisibility(View.Visible);
}else if(y < 200){
perfect.setVisibility(View.Visible);
}else{
low.setVisibility(View.Visible);
}
break;
}