drag not working in relative layout in android studio - android

i have my relative layout in my mainactivity xml but drag is not working the element automatically moves to the corner
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
android:background="#drawable/background"
tools:context=".MainActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="294dp"
app:srcCompat="#drawable/aspertime" />
</RelativeLayout>

setOnTouchListener to ImageView and do your required calculation and perform translation like following.
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
view.setTranslationX(motionEvent.getX());// perform your own calculation
view.setTranslationY(motionEvent.getY());// perform your own calculation
break;
case MotionEvent.ACTION_MOVE:
view.setTranslationX(motionEvent.getX());
view.setTranslationY(motionEvent.getY());
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
However this is very basic sample code.
Happy Coding.
Thanks

Related

NestedScrollView with constraint layout as child not scrolling

I want to scroll the whole layout above keyboard but its not working. I was able to scroll manually but want it to scroll
programatically when a user sets focus on the edit text.
Please help me. Thanks in advance
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
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:id="#+id/scrollView"
android:fillViewport="true"
android:paddingBottom="?attr/actionBarSize">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
......
edit_text_code.setOnFocusChangeListener { view, hasFocus ->
if (hasFocus) {
scrollView.post {
scrollView.fullScroll(NestedScrollView.FOCUS_DOWN)
}
}
}
Method 1:
First get the x/y coordinates of your Edittext using View.getLocationOnScreen (int[] location) ( After the method returns, the array contains the x and y location in that order)
Then do :
scrollView.scrollTo(x, y);
If above method doesn't work try below method :
Method 2:
edit_text_code.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
// put your edit text id below
if (view.getId() ==R.id.DwEdit) {
view.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction()&MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_UP:
view.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
}
return false;
}
});
XML Code :
<EditText
android:id="#+id/DwEdit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minLines="10"
android:scrollbarStyle="insideInset"
android:scrollbars="vertical"
android:overScrollMode="always"
android:inputType="textCapSentences">
</EditText>

How to highlight the selected item in linear layout in android

I am having linear layout, in which it has one imageview and one textview, when i touch the linear layout, it should highlight the image as well as text inside the linear layout with different color. I have tried using set background for the linear layout when it is pressed since i have used ontouch-listener it doesn't shows the color even i tried to change the colors programmatically but it didn't works.
Can anyone tell me how i can change the imageview and textview color when a linear layout is touched.
Xml:
<LinearLayout
android:id="#+id/linear_otherexpense"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:background="#drawable/linearlayout_check"
android:gravity="center"
android:orientation="vertical"
android:weightSum="1">
<ImageView
android:id="#+id/img_otherexpense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:scaleType="centerInside"
android:src="#mipmap/expense"
android:tint="#6666FF" />
<TextView
android:id="#+id/tv_otherexpense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:gravity="center"
android:text="#string/dayexpense"
android:tint="#color/colorPrimary" />
</LinearLayout>
Selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#android:drawable/list_selector_background" />
Code:
li_otherexpense.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
startActivity(new Intent(NewDaybook_Activity.this, AddingNewExpense.class));
NewDaybook_Activity.this.finish();
return false;
}
});
You can use this code. this is working fine for me .May be it will helpfull
findViewById(R.id.linear_otherexpense).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
// When you Touch Down
// U can change Text and Image As per your Functionality
break;
case MotionEvent.ACTION_UP:
//When you Release the touch
// U can change Text and Image As per your Functionality
break;
}
return true;
}
});
Try this,
linearLayout = (LinearLayout) findViewById(R.id.linear_otherexpense);
imageView=(ImageView)findViewById(R.id.img_otherexpense);
linearLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
linearLayout.setBackgroundColor(getResources().getColor(R.color.colorAccent));
imageView.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
return true;
}
});

Rotate image 90 degrees ontouch left or right

So I'm in a bit of a crysis. I'm creating a game and I have a square with 4 different colors on each side. Can't seem to make the square rotate 90deg on right screen touch and -90deg on left screen tap. I can get it to rotate on tap but not stay at the position. Like it to be as smooth as possible.
The Activity:
public class GameActivity extends Activity implements OnTouchListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// Reference to the left and right linear screens
LinearLayout leftTap = (LinearLayout) findViewById(R.id.leftTap);
leftTap.setOnTouchListener(this);
LinearLayout rightTap = (LinearLayout) findViewById(R.id.rightTap);
rightTap.setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// Square itself
ImageView square = (ImageView) findViewById(R.id.square);
// Left and Right Animations
Animation leftAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_left_animation);
Animation rightAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_right_animation);
switch (v.getId()) {
case R.id.leftTap:
// Do left Rotate animation
square.startAnimation(leftAnimation);
break;
case R.id.rightTap:
// Do right Rotate animation
square.startAnimation(rightAnimation);
break;
default:
break;
}
return false;
}
}
The Layout:
<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"
tools:context=".GameActivity"
android:weightSum="1"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/leftTap"
android:visibility="visible"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/square"></LinearLayout>
<ImageView
android:contentDescription="The Square"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="#+id/square"
android:src="#drawable/photo"
android:scaleType="fitCenter" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/rightTap"
android:visibility="visible"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/square"></LinearLayout>
</RelativeLayout>
Left Tap Animation XML:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="500"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-90"/>
</set>
Right Tap Animation XML:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="500"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="90"/>
I could:
switch (v.getId()) {
case R.id.leftClick:
square.setRotation(square.getRotation() - 90);
break;
case R.id.rightClick:
square.setRotation(square.getRotation() + 90);
break;
default:
break;
}
But it won't have the animation (basically linear interpolation) affect. I want to know how can that be done?
Just use ViewPropertyAnimator.
Your OnTouchListener could look like this (although I'm not really sure why you've decided you wanna use OnTouchListener instead of for example OnClickListener):
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
switch (v.getId()) {
case R.id.leftTap:
// Do left Rotate animation
square.animate().rotation(-90).setInterpolator(new LinearInterpolator()).setDuration(500);
break;
case R.id.rightTap:
// Do right Rotate animation
square.animate().rotation(90).setInterpolator(new LinearInterpolator()).setDuration(500);
break;
default:
break;
}
}
return v.onTouchEvent(event);
}
Or you could use rotationBy instead of rotation if that fits your needs better.

Pass click event through the view android

I have frame layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" >
<LinearLayout
android:id="#+id/widgetView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:gravity="center" >
</LinearLayout>
<LinearLayout
android:id="#+id/widgetOverlayFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false" >
</LinearLayout>
First layout contains widget layout, and second one is transparent and receives onLongClick for dragging method.That works, the problem is when i want to interact with widget, to click something, click event is taken by overlayFrame. How can i pass click event trough overlayFrame to widgetView?
EDIT:
Now I'm trying to attach GestureLister to overlayFrame LinearLayout, to somehow see difference between MotionEvent that represent single click and long click. The problem that I'm facing is that OnLongPress in gesture listener is always called whatever I do, single click or long click.
Is there an explanation for this behavior? Tnx!
In my case I added flag to layoutParams of my view, which should have passed a touch event under:
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
This way view will ignore all touches (like view with visibility GONE)
Instead of using GestureListener you can override the onTouchListener in this way.
This will call longPress when the timer runs out and if an up comes in between it will cancel the LongPress
CountDownTimer c;
long time=5000;
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
c= new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
time=millisUntilFinished;
}
public void onFinish() {
Log.i("","LONG PRESS");
}}.start();
break;
case MotionEvent.ACTION_UP:
if (time>0) {
Log.i("example","short click");
c.cancel();
}
break;
}
return true;
}
Maybe setting the overlay's attribute android:focusable="false" or android:focusableInTouchMode="false" would be enough.
You could also make your own overlay widget and override its onInterceptTouchEvent method to return false always.
public class NotTouchableLinearLayout extends LinearLayout {
// Override constructors
// ...
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
Instead of setting a GestureListener on the top layout, you should create your own class that extends LinearLayout and to override it's onTouchEvent method.
There you can implement the logic of long click \ short click etc.
The click events will first be sent to the widget layout, and only if it doesn't handle them (hence it's onTouchEvent returns false), you will get them on the top layout.
edit:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" >
<LinearLayout
android:id="#+id/widgetView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:gravity="center" >
</LinearLayout>
<com.example.touchtesting.MyLinearLayout
android:id="#+id/widgetOverlayFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false" >
</com.example.touchtesting.MyLinearLayout>
</FrameLayout>
change the com.example.touchtesting to the name of your package.
and this is the class:
public class MyLinearLayout extends LinearLayout{
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
private long startClick = 0;
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startClick = ev.getEventTime();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (ev.getEventTime() - startClick < 500) {
Log.i("example","short click");
}
else {
Log.i("example","long click");
}
break;
}
return true;
}
}
To get the long clicks to pass through the widgetView LinearLayout add android:longClickable="true". (For ordinary clicks add android:clickable="true")
So widgetView becomes:
<LinearLayout
android:id="#+id/widgetView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:gravity="center"
android:longClickable="true">
</LinearLayout>

How to set keyboard focus on WebView?

I have a simple WebView example app that has the following layout:
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText android:id="#+id/urlToLoad"
android:hint="Type url to load"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button android:id="#+id/webviewgo"
android:text="Go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false" />
<com.example.exWebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
It works as expected, but I am interested in routing a keyboard event to the WebView. Currently, even if I select the WebView (and scroll etc.), when I type any key, it goes to the EditText control... which is not what I want.
How do I make a keyboard event go to the WebView instead?
According to this thread, all you have to do is set, inside the main activity's OnCreate(), an OnTouchListener() with a requestFocus():
mWebView = (MyWebView) findViewById(R.id.webview);
mWebView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (!v.hasFocus()) {
v.requestFocus();
}
break;
}
return false;
}
});
What this code basically does is lock focus on any down or up event the moment it reaches your view. Note how it returns false, so that the event can further propagate to other views, as if it weren't handled.

Categories

Resources