Android app crashes when touched outside the ImageView - java

When i touched the ImageView it display the color from the image but when i touched outside the image the app crashes.
Here's my xml code:
<ImageView
android:id="#+id/colorimage"
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="#drawable/color" />
<ImageView
android:id="#+id/displaycolor"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/colorimage"/>
And here is the main code:
mImageView.setDrawingCacheEnabled(true);
mImageView.buildDrawingCache(true);
mImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){
Bitmap bitmap = mImageView.getDrawingCache();
int pixel = bitmap.getPixel((int)event.getX(), (int)event.getY());
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
display.setBackgroundColor(Color.rgb(r , g , b));
}
return true;
}
});
Logcat error message:
Error Logs

Change the line if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) to :
if(v.getId() == R.id.colorimage){
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
{........}
}
The on touch listener has been set to the whole activity not a particular view and the bitmap operation cannot be done on the other views except this one so the view so it is crashing.

Related

how to set listener for imagebutton to notice when touched position moved out or moved into the imagebutton?

I am making a simple piano app for android with java, I just set setOnTouchedListener to each ImageButtons. if MotionEvent is ACTION_DOWN, The piano sound played. and if MotionEvent is ACTION_UP, The piano sound stopped. But if I drag my finger out of ImageButton, the sound still playing.
I want to make the sound stopped when I drag my finger out of ImageButton.
and If I drag into ImageButton, I want the sound is played again...
what listener should I use?
public class KeyBoardListener implements View.OnTouchListener {
private SoundPool spool;
private int soundkeys[];
private int pitch;
private boolean isWhite;
public void setInitSound(SoundPool spool, int soundkeys[], int pitch, boolean isWhite){ // 리스너에서 재생할 SoundPool 가져옴
this.soundkeys=soundkeys;
this.spool=spool;
this.pitch=pitch;
this.isWhite=isWhite;
}
#Override // 건반 이미지뷰 터치리스너
public boolean onTouch (View view, MotionEvent motionEvent){
int currentpitch=pitch+KeyboardActivity.octave.get()*12; // 옥타브 값 적용
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
float y = motionEvent.getY(); // 터치한 Y좌표와 건반 최대 Y좌표 이용해 벨로시티 값 계산
float ymax=view.getHeight();
y=y/ymax;
PlayNote.noteOff(spool, currentpitch);
PlayNote.noteOn(spool, soundkeys[currentpitch], currentpitch, y);
if(isWhite)
view.setBackgroundColor(Color.parseColor("#B0B0B0"));
else
view.setBackgroundResource(R.drawable.key_black_push);
}
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
if (KeyboardActivity.sustain.get() == false) // 서스테인 기능이 꺼져있을 때만 소리 정지
PlayNote.noteOff(spool, currentpitch);
if(isWhite)
view.setBackgroundColor(Color.WHITE);
else
view.setBackgroundResource(R.drawable.key_black);
}
return false;
}
}

How to make a button bigger when pressed? (Android Studios)

I'm working on an app in Android studios and would like my customised button to get bigger when pressed and go back to the default defined state when released. I wrote an xml file to define my button but it didn't work. Here's my xml file for the custom button:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/play_button_pressedhdpi"
android:state_pressed="true" />
<item android:drawable="#drawable/play_button_defaulthdpi"
android:state_focused="true" />
<item android:drawable="#drawable/play_button_defaulthdpi" />
</selector>
This doesn't seem to work. Any help would be appreciated.
Edit:
I just tried the following code as mentioned in the first answer below:
button1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
//sendMessage("Key1\n");
lp.width = 200;
lp.height = 200;
button1.setLayoutParams(lp);
}
if(event.getAction() == MotionEvent.ACTION_UP) {
lp.width=90;
lp.height=90;
button1.setLayoutParams(lp);
}
return false;
}
});
This makes sense but didn't work for some reason.
Any help would be appreciated...
I was finally able to solve the problem. I created two separate images of two different sizes and used the setOnTouchListener() to assign the appropriate image to the button for each of the states ACTION_DOWN and ACTION_UP in the following manner:
button1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
float x = (float) 1.25;
float y = (float) 1.25;
button1.setScaleX(x);
button1.setScaleY(y);
button1.setBackgroundResource(R.drawable.blue_220);
return true;
}
else if(event.getAction() == MotionEvent.ACTION_UP)
{
float x = 1;
float y = 1;
button1.setScaleX(x);
button1.setScaleY(y);
button1.setBackgroundResource(R.drawable.blue_206);
}
return false;
}
});
Result as desired.
I use MotiovEvent in this way to resize my button:
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
RelativeLayout.LayoutParams lp = (LayoutParams) b.getLayoutParams();
if(event.getAction() == MotionEvent.ACTION_DOWN) {
sendMessage("key1\n");
lp.width=140;
lp.height=140;
button.setLayoutParams(lp);
}
if(event.getAction() == MotionEvent.ACTION_UP) {
lp.width=90;
lp.height=90;
button.setLayoutParams(lp);
}
return false;
}
});
Hope it helps.

Android - Detecting when user touches a drawable left

I have a TextView that contains a DrawableRight, what I want to do is detecting when the user presses that icon in drawableRight, is that possible ? and if it is how can I do it ?
PS: I am working inside a fragment
TextView XML
<TextView
android:id="#+id/mTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
android:textSize="22dp"
android:drawableRight="#mipmap/icn" //this is the drawable
/>
mTitle.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_RIGHT = 2;
if (event.getAction() == MotionEvent.ACTION_UP) {
if (event.getRawX() >= (mTitle.getRight() - mTitle.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
//drawable pressed
return true;
}
}
return false;
}
});

Creating a Drag and Drop ImageButton

I have looked tutorials on how to make my imagebutton capable of drag and drop. With the code I have the imagebutton just disappears when I click it. and when I click anywhere else it does not come back.
Here is my code for the imagebutton:
mainHut = (ImageButton) findViewById(R.id.mainHut);
mainHut.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
Toast.makeText(getApplicationContext(), "in the movement", Toast.LENGTH_SHORT).show();
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
mainHutSelected = true;
}//end if
if (event.getAction() == MotionEvent.ACTION_UP)
{
if (mainHutSelected == true)
{
mainHutSelected = false;
}//end if
}//end if
else if (event.getAction() == MotionEvent.ACTION_MOVE)
{
if (mainHutSelected == true)
{
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(50, 50);
params.setMargins((int)event.getRawX() - 25, (int) event.getRawY() - 50, 0, 0);
layout = (LinearLayout) findViewById(R.id.gllayout);
layout.removeView(mainHut);
layout.addView(mainHut, params);
}//end if
}//end else
return false;
}//end onTouch function
});
here is the xml for the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gllayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/bgm" >
<ImageButton
android:id="#+id/mainHut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/mainhut" />
</LinearLayout>
Any help is appreciated. Thanks.
To answer my own question...this is how I fixed my issue. It took me a long time to figure this out but here it is. The parameters are a little messy when it comes to my own imagebutton so I will have to figure out what to use to keep my finger in the center of the button, but this moves the button like I was wanting:
button.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
if (me.getAction() == MotionEvent.ACTION_MOVE )
{
LayoutParams params = new LayoutParams(v.getWidth(), v.getHeight());
params.setMargins((int)event.getRawX() - v.getWidth()/2, (int)(event.getRawY() - v.getHeight()), (int)event.getRawX() - v.getWidth()/2, (int)(event.getRawY() - v.getHeight()));
v.setLayoutParams(params);
}
return false;
}
});

Android multitouch issue

So I'm working on a game where two players play simultaneously on one screen. For the sake of simplicity let's say both players have one button on their side of the screen, buttons B[0] and B[1]. I want to implement multitouch so that both buttons can be pressed with no unresponsiveness, but as soon as one of them does ACTION_DOWN on his button, the other one becomes unresponsive. I read all the duplicate questions and understood that the second touch would be referenced as ACTION_POINTER_DOWN so I wrote this piece of code:
#Override
public boolean onTouch(View buttonPressed, MotionEvent action)
{
if(buttonPressed.getId()==B[0].getId())
{
if(action.getAction() == MotionEvent.ACTION_DOWN || action.getAction() == MotionEvent.ACTION_POINTER_DOWN)
B[0].setImageDrawable(BPressed[0]);
if(action.getAction() == MotionEvent.ACTION_UP || action.getAction() == MotionEvent.ACTION_POINTER_UP)
B[0].setImageDrawable(BOk[0]);
}
if(buttonPressed.getId()==B[1].getId())
{
if(action.getAction() == MotionEvent.ACTION_DOWN || action.getAction() == MotionEvent.ACTION_POINTER_DOWN)
B[1].setImageDrawable(BPressed[1]);
if(action.getAction() == MotionEvent.ACTION_UP || action.getAction() == MotionEvent.ACTION_POINTER_UP)
B[1].setImageDrawable(BOk[1]);
}
return true;
}
So as far I can tell if I put 1 finger on B[0] and leave it there (no ACTION_UP) and then put another on B[1] the listener should fire onTouch(B[1],ACTION_POINTER_DOWN) but i think it doesn't since when I do that B[0] has BPressed drawable and B[1] has BOk drawable. Where did I go wrong? Sorry if I made a duplicate, but I read everything and can't seem to find a simple solution. Every solution regarding this issue I found gives much more than I need.
Both buttons are connected with the listener like this:
B[0].setOnTouchListener(this);
B[1].setOnTouchListener(this);
I've read this:
ACTION_POINTER_DOWN and ACTION_POINTER_UP are fired whenever a secondary pointer goes down or up.
But it doesn't seem to be true.
EDIT:
The new code, still the same result:
#Override
public boolean onTouch(View buttonPressed, MotionEvent action)
{
if( buttonPressed.getId()==B[1].getId() )
Toast.makeText(context, "One", 500).show();
int act = action.getAction() & MotionEvent.ACTION_MASK;
if(buttonPressed.getId()==B[0].getId())
{
if(act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_POINTER_DOWN)
B[0].setImageDrawable(BPressed[0]);
if(act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP)
B[0].setImageDrawable(BOk[0]);
}
if(buttonPressed.getId()==B[1].getId())
{
if(act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_POINTER_DOWN)
B[1].setImageDrawable(BPressed[1]);
if(act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP)
B[1].setImageDrawable(BOk[1]);
}
return true;
}
Also, the toast:
if( buttonPressed.getId()==B[1].getId() )
Toast.makeText(context, "One", 500).show();
can never be seen if I keep my finger on B[0].
After masking:
Something changed. Let's say I hold my finger on B[0]. Before the masking when I press B[1] nothing happens. After masking if I keep my finger on B[0], and I tap my finger ANYWHERE on the screen it cycles the B[0]. So if I go:
finger1_DOWN on B[0] it changes to Pressed drawable
while(1)
{
finger2_DOWN anywhere nothing changes
finger2_UP anywhere B[0] changes to Ok drawable
}
I create my imagebuttons in OnCreate:
B[0] = (ImageButton) findViewById(R.id.ImageButton05);
B[0].setOnTouchListener(this);
B[1] = (ImageButton) findViewById(R.id.ImageButton15);
B[1].setOnTouchListener(this);
I tried jboi's approach. I don't care if the button was pressed first or second so I just did this:
private class MPListener implements OnTouchListener
{
#Override
public boolean onTouch(View buttonPressed, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(buttonPressed.getId()==B[0].getId())
B[0].setImageDrawable(BPressed[0]);
if(buttonPressed.getId()==B[1].getId())
B[1].setImageDrawable(BPressed[1]);
}
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(buttonPressed.getId()==B[0].getId())
B[0].setImageDrawable(BOk[0]);
if(buttonPressed.getId()==B[1].getId())
B[1].setImageDrawable(BOk[1]);
}
return true;
}
}
I removed implements onTouchListener from my activity and added
B[0].setOnTouchListener(new MPListener());
B[1].setOnTouchListener(new MPListener());
Nothing changed. I can still press both buttons independently, but not at the same time.
EDIT:
So I made a fresh new activity in case something else was the problem. Here's my new activity's full code:
package com.example.projectname;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class About extends Activity
{
private class MPListener implements OnTouchListener
{
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(v.getId()==B[0].getId())
B[0].setImageDrawable(Bok[0]);
if(v.getId()==B[1].getId())
B[1].setImageDrawable(Bok[1]);
}
else if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(v.getId()==B[0].getId())
B[0].setImageDrawable(Bpressed[0]);
if(v.getId()==B[1].getId())
B[1].setImageDrawable(Bpressed[1]);
}
return true;
}
}
ImageView[] B;
Drawable[] Bok,Bpressed;
#Override
protected void onCreate(Bundle savedInstanceState)
{
//standard oncreate stuff
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_about);
Context context=getApplicationContext();
B=new ImageView[2];
Bok=new Drawable[2];
Bpressed=new Drawable[2];
Bok[0] = context.getResources().getDrawable(R.drawable.bblue);
Bok[1] = context.getResources().getDrawable(R.drawable.bpurp);
Bpressed[0] = context.getResources().getDrawable(R.drawable.bpressedblue);
Bpressed[1] = context.getResources().getDrawable(R.drawable.bpressedpurp);
B[0] = (ImageView) findViewById(R.id.imageView1);
B[1] = (ImageView) findViewById(R.id.imageView2);
B[0].setImageDrawable(Bok[0]);
B[1].setImageDrawable(Bok[1]);
B[0].setOnTouchListener(new MPListener());
B[1].setOnTouchListener(new MPListener());
}
}
Everything is the same as always. As soon as I press one button the other one goes unresponsive.
Android can sort out for you, what was pressed in what order and if it is still touched or not. Just give the two Buttons different listeners. Something like this code:
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("TEST", "Begin onCreate");
super.onCreate(savedInstanceState);
Log.d("TEST", "End onCreate");
setContentView(R.layout.test);
findViewById(R.id.upperTouchable).setOnTouchListener(new MyTouchListener());
findViewById(R.id.lowerTouchable).setOnTouchListener(new MyTouchListener());
}
private boolean lowerIsTouched = false;
private boolean upperIsTouched = false;
private void setInfo() {
if(lowerIsTouched && upperIsTouched)
((TextView) findViewById(R.id.info)).setText("both touched");
else if(lowerIsTouched)
((TextView) findViewById(R.id.info)).setText("only lower is touched");
else if(upperIsTouched)
((TextView) findViewById(R.id.info)).setText("only upper is touched");
else
((TextView) findViewById(R.id.info)).setText("non is touched");
((TextView) findViewById(R.id.lowerTouchable)).setText(lowerIsTouched? "touched":"not touched");
((TextView) findViewById(R.id.upperTouchable)).setText(upperIsTouched? "touched":"not touched");
}
private class MyTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
if(v.getId() == R.id.lowerTouchable)
lowerIsTouched = true;
else if(v.getId() == R.id.upperTouchable)
upperIsTouched = true;
setInfo();
}
else if(event.getAction() == MotionEvent.ACTION_UP) {
if(v.getId() == R.id.lowerTouchable)
lowerIsTouched = false;
else if(v.getId() == R.id.upperTouchable)
upperIsTouched = false;
setInfo();
}
return true;
}
}
and the corresponding layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#FFFFFFFF"
android:text="Non touched"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/upperTouchable"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="Not touched"
android:background="#FFF0F0F0"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/lowerTouchable"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="Not touched"
android:background="#FFFFFFFF"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

Categories

Resources