Adding imageView on ViewGroup with setOnTouchListener - android

EDIT: This question was solved!
i'm facing with a, hopefully, simple problem. What i need it's to show/add image on onTouch position when the user click on the Image/Area.
This is the layout:
activity_test_diff.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TestDiff"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/relative_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ImageView
android:id="#+id/img_rectangle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:visibility="invisible"/>
<ImageView
android:id="#+id/img_test_diff1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter" />
<ImageView
android:id="#+id/click_check_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/check_green_48dp"/>
<ImageView
android:id="#+id/click_check_ko"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:src="#drawable/close_red_48dp"/>
</RelativeLayout>
<ImageView
android:id="#+id/img_test_diff2"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"
android:scaleType="fitCenter"/>
</LinearLayout>
The parent group of the Relative Layout it's a LinearLayout, but i don't care if someone touch outside of RelativeLayout. This is the code to handle the touch:
TestDiff.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_diff);
RelativeLayout relative = (RelativeLayout) findViewById(R.id.relative_layout);
relative.setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, 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:
int x = (int) ev.getX();
int y = (int) ev.getY();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
ImageView iv = new ImageView(getApplicationContext());
lp.setMargins(x, y, 0, 0);
iv.setLayoutParams(lp);
iv.setImageDrawable(getResources().getDrawable(
R.drawable.check_green_48dp));
((ViewGroup) v).addView(iv);
return true;
case MotionEvent.ACTION_UP:
// On the UP, we do the click action.
// The hidden image (img_rectangle) has three different hotspots on it.
// The colors are red, blue, and yellow.
// Use img_rectangle to determine which region the user
return true;
default:
return false;
}
}
And this is the coming error:
Attempt to invoke virtual method 'void android.widget.RelativeLayout.setOnTouchListener(android.view.View$OnTouchListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
Mean someone can figure out what's happening!
Thanks

on the xml layout you have :
<RelativeLayout
android:id="#+id/relative_layout"
in the java code you have
RelativeLayout relative = (RelativeLayout) findViewById(R.id.layout_relative);
you reversed relative & layout words

Related

android:layout_toLeftOf in RelativeLayout not working when I setX on left view

I have a RelativeLayout that contains two ImageViews and a View between them, both ImageViews are aligned to the View sibling [i.e. right ImageView is aligned to right side of the view, same with the left].
like this:
<RelativeLayout
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="horizontal"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="106dp">
<ImageView
android:id="#+id/img1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/euqualizer"
android:scaleType="fitXY"
app:srcCompat="#mipmap/ic_launcher_round" />
<View
android:id="#+id/euqualizer"
android:layout_width="20dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:background="#000" />
<ImageView
android:id="#+id/img2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/euqualizer"
android:layout_alignParentRight="true"
android:scaleType="fitXY"
app:srcCompat="#mipmap/ic_launcher" />
</RelativeLayout>
and in the java code I want to move the view's location according to the direction of the touch motion i.e. using setX() on the view.
like this:
img1.setOnTouchListener(touchListener);
img2.setOnTouchListener(touchListener);
View.OnTouchListener touchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startDrag_X = event.getX();
break;
case MotionEvent.ACTION_MOVE:
float x_delta = event.getX() - startDrag_X;
euqualizer.setX(euqualizer.getX() + x_delta);
break;
case MotionEvent.ACTION_UP:
startDrag_X = -1;
break;
}
return true;
}
};
But for some reason although, the view does successfully relocate itself as I expected it to do, but the ImageViews which are aligned to the views sides do not move at all
what am I doing wrong?

Click listeners on a transparent layout with background items click-able

I have created an activity which is transparent. The background is click-able, anything can be performed on mobile with activity opened. Now I want to set click listeners on the textview that is inside the transparent activity. I have searched but didn't find anything.
Here is the code to my layout :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent">
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Here is the Java code that i am using :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show();
}
});
}
I want the hello world to be click-able as well as other apps for example, Chrome, messaging, menu etc.
What you are trying to achieve is not possible with an activity. When you use activity it covers all of the screen and any touch done on screen will only accessible by that activity(If it transparent or not, this does not matter).
My suggestion is, try to use a widget instead of activity. It may fulfill your requirement. I suggest you to use any floating widget or permanently place that widget into center of the screen.
Below link may helpful for you.
Chat Widget
Floating widget
you don't have to use activity for this purpose. you just call it form service class.
windowManager2 = (WindowManager)getSystemService(WINDOW_SERVICE);
LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view=layoutInflater.inflate(R.layout.popup_incoming, null);
params=new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity=Gravity.CENTER|Gravity.CENTER;
params.x=0;
params.y=0;
windowManager2.addView(view, params);
view.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager2.updateViewLayout(view, params);
return true;
}
return false;
}
});
txtNameIncoming = (TextView)view.findViewById(R.id.NameIncoming);
txtIncomingnumber = (TextView)view.findViewById(R.id.txtIncomingnumber);
txtIncomingnumber.setText("You have Incoming Call from " + PhoneStateReceiver.savedNumber);
btnClose = (Button) view.findViewById(R.id.buttonClose);
btnClose.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
clearView(v.getContext());
}
});
xml will be:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:background="#0090FF"
android:padding="10dp"
android:keepScreenOn="true" >
<TextView
android:id="#+id/NameIncoming"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="Incoming Caller"
android:textColor="#fff" />
<TextView
android:id="#+id/txtIncomingnumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_below="#+id/NameIncoming"
android:text="Incoming Call Number"
android:textColor="#fff" />
<Button
android:id="#+id/buttonClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Close" />
now modify it for yourself.

android view dosen't draw correctly

xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frame_living_root_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<SurfaceView
android:id="#+id/player_surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<android.opengl.GLSurfaceView
android:id="#+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:visibility="gone" />
<com.netease.nimlib.sdk.avchat.model.AVChatSurfaceViewRenderer
android:id="#+id/video_render"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<com.netease.nimlib.sdk.avchat.model.AVChatSurfaceViewRenderer
android:id="#+id/bypass_video_render"
android:layout_width="110dip"
android:layout_height="150dip"
android:layout_gravity="right|end|bottom"
android:layout_marginBottom="70dip"
android:layout_marginEnd="10dip"
android:layout_marginRight="10dip"
android:visibility="gone" />
<!--root view is FrameLayout with 40dip layout_margin and is a little complex-->
<include layout="#layout/layout_live_top" />
<!-- the content of this view will be scroll by touch event-->
<com.example.SimpleSlideView
android:id="#+id/slide_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- yellow background-->
<ImageView
android:id="#+id/yellow_child_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0" />
</com.example.SimpleSlideView>
</FrameLayout>
SimpleSlideView:
public class SimpleSlideView extends FrameLayout {
public int screenWidth;
public int screenHeight;
private float lastY;
public SimpleSlideView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
initScreenSize(context);
scrollTo(0, screenHeight);
}
private void initScreenSize(#NonNull Context context) {
DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
float rawY = ev.getRawY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = rawY;
break;
case MotionEvent.ACTION_MOVE:
final int delta = (int) (rawY - lastY);
scrollTo(0, getScrollY() - (delta));
lastY = rawY;
break;
case MotionEvent.ACTION_UP:
scrollTo(0, screenHeight);
break;
}
return true;
}
}
I want to write a SimpleSlideView that can scroll it content down by pull down on it SimpleSlideView works as expected in lightweight XML but a little weird in complex XML.
#layout/layout_live_top contain a FrameLayout root view with 40dip layout_margin and layout_live_top is a little complex.
SimpleSlideView is a MatchParent view without padding and margin, same with it child #+id/yellow_child_view which has a yellow background.
Something weird is happen when quickly pulldown:
The yellow area has 40dip margin left and right at the beginning of the pull and then it become match parent.SimpleSlideView seems to be affected by the margin(40dip) of other view, it should be matched parent while pulling down.I don't know why this happened.It is because of my complex XML?

Changing width from RelativeLayout not affect children

My code
<RelativeLayout
android:id="#+id/leftSelectorView"
android:layout_width="50dp"
android:layout_height="match_parent">
<View
android:id="#+id/grayBgLeft"
android:focusableInTouchMode="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#bf484349" />
<RelativeLayout
android:id="#+id/leftBorderView"
android:layout_marginLeft="20dp"
android:layout_width="30dp"
android:layout_height="match_parent">
<ImageView
android:id="#+id/boxLeft"
android:focusableInTouchMode="false"
android:layout_marginLeft="15dp"
android:layout_width="15dp"
android:layout_height="match_parent"
android:src="#mipmap/box_selector"
android:scaleType="fitXY" />
</RelativeLayout>
</RelativeLayout>
i'm moving the leftSelectorView width programmatically
leftSelectorView.getLayoutParams().width = 150;
and the View child is not affected.
If i have a child inside RelativeLayout with match_parent in width and modify the width from RelativeLayout, how can update the width of child?
Using the requestLayout now update al childrens. (Thanks to #FunkTheMonk)
Now another problem has arisen with this. The RelativeLayout I'm trying to move, takes a few jumps as if sometimes take the new position and then the old position
My code:
leftBorderView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_MOVE) {
int xMove = (int) event.getX();
Log.e("onTouch", "xMove===> " + xMove);
int widthMove = xMove < 50 ? 50 : 50 + xMove;
RelativeLayout.LayoutParams parms = new RelativeLayout.LayoutParams(widthMove, ViewGroup.LayoutParams.MATCH_PARENT);
leftSelectorView.setLayoutParams(parms);
grayBgLeft.requestLayout();
}
return true;
}
});

How to set Image position relative to another Image on Android

I try to explain my problem. I have two ImageViews.
One of them is the background image and large as well.
This background image has also a zoom function. The other Image is a small image with size of 36x36.
The small image can be moved around the screen:
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
//Definition MotionEvent.ACTION_MASK: Bit mask of the parts of the action code that are the action itself.
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:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setLayoutParams(layoutParams);
break;
}
viewGroup.invalidate();
return true;
}
If i zoom in the background image, the small image doesn't zoom. It's position is absolute to the screen and not to the Image.
How can i make the small Image to be relative to the large Image?
I hope it's clear what my Problem is.
<?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:id="#+id/root">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/skizze"
android:scaleType="matrix"
/>
<ImageView
android:layout_width="55dp"
android:layout_height="55dp"
android:id="#+id/feuerloescher"
android:layout_gravity="center_horizontal|top"
android:layout_alignParentTop="false"
android:src="#drawable/feuerloescher"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="false" />
</RelativeLayout>
try with android:layout_below="#id/skizze"
Try as following xml code
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/skizze"
android:scaleType="matrix"
/>
<ImageView
android:layout_width="55dp"
android:layout_height="55dp"
android:id="#+id/feuerloescher"
android:layout_gravity="center_horizontal|top"
android:layout_alignParentTop="false"
android:src="#drawable/feuerloescher"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="false"
android:layout_below="#id/skizze" />
I know this is an old post however just in case it helps I just had this same issue and was able to resolve it as follows.
android:layout_alignTop="#id/app_bg_fill"
"alignTop" seemed to be the key line. Full code follows.
<?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:background="#drawable/app_bg_fill"
android:orientation="vertical" >
<ImageView
android:id="#+id/app_bg_fill"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="60dp"
android:layout_marginTop="100dp"
android:scaleType="fitEnd"
android:src="#drawable/guide_item_2f"
android:background="#drawable/view_frame_style" />
<TextView
android:layout_width="match_parent"
android:layout_height="100sp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="20sp"
android:layout_marginRight="20sp"
android:layout_marginBottom="20sp"
android:background="#00000000"
android:layout_centerInParent="true"
android:padding="12sp"
android:text="SomeText"
android:layout_alignTop="#id/app_bg_fill"
android:textColor="#000000" />
</RelativeLayout>

Categories

Resources