how to drop apple inside the basket using animation in android? - java

I need a help to animating the filling of basket with apple in android by drop apple inside bucket image. Below is my drag and drop code in this I am dragging and dropping apple from one place to other place.
#Override
public boolean onDrag(View v, DragEvent event) {
// Store the action type for the incoming event
final int action = event.getAction();
// Handles each of the expected events
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
// Invalidate the view to force a redraw in the new tint
v.invalidate();
// Returns true to indicate that the View can accept the
// dragged data.
return true;
case DragEvent.ACTION_DRAG_ENTERED:
v.invalidate();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
// Ignore the event
return true;
case DragEvent.ACTION_DRAG_EXITED:
v.invalidate();
return true;
case DragEvent.ACTION_DROP:
v.invalidate();
if (v instanceof ImageView) {
ImageView dropView = (ImageView) v;
Drawable dropViewDrawable = dropView.getDrawable();
Log.v("dropViewDrawable", "" + dropViewDrawable);
for (int i = 0; i < numberOfObject; i++) {
if (containerImageViewList.get(i).getDrawable() == null) {
containerImageViewList.get(i).setImageResource(R.drawable.sp_glass_cut);
if (selectedImageColor.equals(getResources().getString(R.string.title_images_color_grey))) {
containerImageViewList.get(i).setImageBitmap(CommonMethods.convertColoredImageIntoBlackAndWhiteImage(containerImageViewList.get(i)));
}
break;
}
}
dragImageView.setImageBitmap(null);
successCount++;
} else {
CommonMethods.showSweetAlertDialog(SPLevelOneMoveObjectTBActivity.this, false);
}
return true;
case DragEvent.ACTION_DRAG_ENDED:
v.invalidate();
Log.v("ACTION_DRAG_ENDED", "ACTION_DRAG_ENDED");
if (!isSuccess && !isFail) {
isFail = true;
CommonMethods.showSweetAlertDialog(SPLevelOneMoveObjectTBActivity.this, false);
return true;
}
return true;
default:
break;
}
return false;
}
now how to animate it and show the apple inside the basket?

Hi You can make your basket with the help of Empty LinearLayout(or Any other Layout like RelativeLayout and ConstraintLayout) and then assign the border to it like this
res/drawable/basket_border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners
android:topLeftRadius="0dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="45dp"
android:bottomRightRadius="45dp"
/>
<gradient
android:angle="45"
android:centerX="35%"
android:centerColor="#9BA8A3"
android:startColor="#6BA9E8"
android:endColor="#FFFFFF"
android:type="linear"
/>
<padding
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
/>
<size
android:width="270dp"
android:height="120dp"
/>
<stroke
android:width="5dp"
android:color="#878787"
/>
</shape>
or you can use a 9 patch image of a basket in the background also
here I have used the TextView and made it circle rather than apple using below file
res/drawable/border_circle.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- <gradient
android:angle="0"
android:startColor="#f00"
android:centerColor="#android:color/transparent"
android:centerX="0.01" />-->
<stroke android:width="5dp" android:color="#3AFB03" />
<solid android:color="#FAFB03" />
<corners android:radius="4dp" />
</shape>
You can use a 9patch apple image and ImageView instead.
Now go to your main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="260dp"
android:layout_height="98dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="#drawable/basket_border"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="108dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:gravity="bottom"
android:orientation="horizontal"
android:weightSum="4">
<TextView
android:id="#+id/textView"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="#drawable/border_circle"
android:gravity="center"
android:text="Text 1"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
android:textColor="#android:color/holo_blue_bright"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="284dp"/>
<TextView
android:id="#+id/textView2"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="#drawable/border_circle"
android:gravity="center"
android:text="Text 2"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
android:textColor="#android:color/holo_red_dark"
tools:layout_editor_absoluteX="90dp"
tools:layout_editor_absoluteY="284dp"/>
<TextView
android:id="#+id/textView3"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="#drawable/border_circle"
android:gravity="center"
android:text="Text 3"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
android:textColor="#android:color/holo_purple"
tools:layout_editor_absoluteX="162dp"
tools:layout_editor_absoluteY="284dp"/>
<TextView
android:id="#+id/textView4"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="#drawable/border_circle"
android:gravity="center"
android:text="Text 4"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
tools:layout_editor_absoluteX="230dp"
tools:layout_editor_absoluteY="283dp"/>
</LinearLayout>
</LinearLayout>
you can use your concept of drag-drop to put the ImageView(apple) into the LinearLayout of id linearLayout1 which is basket so here you can apply normal animation on the ImageView(apple) while adding to LinearLayout(basket)

Related

can not working windowsoftinputmode in android [duplicate]

I would like to adjust/re-size the layout when the soft-keyboard activated, as below:
Before and After:
Found couple resources in SO:
How to keep all fields and texts visible while the soft keyboard is shown
android soft keyboard spoils layout when appears
Adjust layout when soft keyboard is on
But the questions & answers are rather ambiguous, here's the question with clearer picture of what I want.
Requirements:
It should work on phone with any screen sizes.
Noticed that the margin/padding space at "FACEBOOK" and "Sign Up for
Facebook" has changed before and after.
No scroll view is involved.
Just add
android:windowSoftInputMode="adjustResize"
in your AndroidManifest.xml where you declare this particular activity and this will adjust the layout resize option.
some source code below for layout design
<?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:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="FaceBook"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="username" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/editText1"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="password" />
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/editText2"
android:layout_centerHorizontal="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="20dp"
android:text="Log In" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="17dp"
android:gravity="center"
android:text="Sign up for facebook"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
This question has beeen asked a few years ago and "Secret Andro Geni" has a good base explanation and "tir38" also made a good attempt on the complete solution, but alas there is no complete solution posted here.
I've spend a couple of hours figuring out things and here is my complete solution with detailed explanation at the bottom:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/mainLayout"
android:layout_alignParentTop="true"
android:id="#+id/headerLayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:text="facebook"
android:textStyle="bold"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:id="#+id/mainLayout"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText1"
android:ems="10"
android:hint="Email or Phone"
android:inputType="textVisiblePassword">
<requestFocus />
</EditText>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="#+id/editText2"
android:ems="10"
android:hint="Password"
android:inputType="textPassword" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="#+id/button1"
android:text="Log In"
android:onClick="login" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#+id/mainLayout"
android:id="#+id/footerLayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView2"
android:text="Sign Up for Facebook"
android:layout_centerHorizontal="true"
android:layout_alignBottom="#+id/helpButton"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/helpButton"
android:text="\?"
android:onClick="help" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
And in AndroidManifest.xml, don't forget to set:
android:windowSoftInputMode="adjustResize"
on the <activity> tag that you want such layout.
Thoughts:
I've realized that RelativeLayout are the layouts that span thru all available space and are then resized when the keyboard pops up.
And LinearLayout are layouts that don't get resized in the resizing process.
That's why you need to have 1 RelativeLayout immediately after ScrollView to span thru all available screen space. And you need to have a LinearLayout inside a RelativeLayout else your insides would get crushed when the resizing occurs. Good example is "headerLayout". If there wouldn't be a LinearLayout inside that RelativeLayout "facebook" text would get crushed and wouldn't be shown.
In the "facebook" login pictures posted in the question I've also noticed that the whole login part (mainLayout) is centered vertical in relation to the whole screen, hence the attribute:
android:layout_centerVertical="true"
on the LinearLayout layout. And because mainLayout is inside a LinearLayout this means that that part does't get resized (again see picture in question).
Add this line in your Manifest where your Activity is called
android:windowSoftInputMode="adjustPan|adjustResize"
or
you can add this line in your onCreate
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
It can work for all kind of layout.
add this to your activity tag in AndroidManifest.xml
android:windowSoftInputMode="adjustResize"
for example:
<activity android:name=".ActivityLogin"
android:screenOrientation="portrait"
android:theme="#style/AppThemeTransparent"
android:windowSoftInputMode="adjustResize"/>
add this on your layout tag in activitypage.xml that will change its position.
android:fitsSystemWindows="true"
and
android:layout_alignParentBottom="true"
for example:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:fitsSystemWindows="true">
Android Developer has the right answer, but the provided source code is pretty verbose and doesn't actually implement the pattern described in the diagram.
Here is a better template:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- stuff to scroll -->
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<!-- footer -->
</FrameLayout>
</RelativeLayout>
</ScrollView>
Its up to you to decide what views you use for the "scrolling" and "footer" parts. Also know that you probably have to set the ScrollViews
fillViewPort .
This makes it possible to show any wanted layout previously hidden by the keyboard.
Add this to the activity tag in AndroidManifest.xml
android:windowSoftInputMode="adjustResize"
Surround your root view with a ScrollView, preferably with scrollbars=none. The ScrollView will properly not change any thing with your layout except be used to solve this problem.
And then set fitsSystemWindows="true" on the view that you want to make fully shown above the keyboard.
This will make your EditText visible above the keyboard, and make it possible to scroll down to the parts below the EditText but in the view with fitsSystemWindows="true".
android:fitsSystemWindows="true"
For example:
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
...
</android.support.constraint.ConstraintLayout>
</ScrollView>
If you want to show the full part of fitsSystemWindows="true" view above the keyboard in the moment the keyboard appears, you will need some code to scroll the view to the bottom:
// Code is in Kotlin
setupKeyboardListener(scrollView) // call in OnCreate or similar
private fun setupKeyboardListener(view: View) {
view.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
view.getWindowVisibleDisplayFrame(r)
if (Math.abs(view.rootView.height - (r.bottom - r.top)) > 100) { // if more than 100 pixels, its probably a keyboard...
onKeyboardShow()
}
}
}
private fun onKeyboardShow() {
scrollView.scrollToBottomWithoutFocusChange()
}
fun ScrollView.scrollToBottomWithoutFocusChange() { // Kotlin extension to scrollView
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY + height)
smoothScrollBy(0, delta)
}
Full layout example:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<RelativeLayout
android:id="#+id/statisticsLayout"
android:layout_width="match_parent"
android:layout_height="340dp"
android:background="#drawable/some"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/logoImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:src="#drawable/some"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/authenticationLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="20dp"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/statisticsLayout">
<android.support.design.widget.TextInputLayout
android:id="#+id/usernameEditTextInputLayout"
android:layout_width="match_parent"
android:layout_height="68dp">
<EditText
android:id="#+id/usernameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/passwordEditTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/usernameEditTextInputLayout">
<EditText
android:id="#+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/passwordEditTextInputLayout"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:layout_marginTop="20dp" />
<Button
android:id="#+id/forgotPasswordButton"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_below="#id/loginButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
For those using ConstraintLayout, android:windowSoftInputMode="adjustPan|adjustResize" will not work.
What you can do is use a soft keyboard listener, set constraints of the views from bottom to bottom of the upper views, then set a vertical bias for each view (as a positional percentage between constraints) to a horizontal guideline (also positioned by percentage, but to the parent).
For each view, we just need to change app:layout_constraintBottom_toBottomOf to #+id/guideline when the keyboard is shown, programmatically of course.
<ImageView
android:id="#+id/loginLogo"
...
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.15" />
<RelativeLayout
android:id="#+id/loginFields"
...
app:layout_constraintVertical_bias=".15"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/loginLogo">
<Button
android:id="#+id/login_btn"
...
app:layout_constraintVertical_bias=".25"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/loginFields"/>
Generally a soft keyboard takes up no more than 50% of the height of the screen. Thus, you can set the guideline at 0.5.
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"/>
Now programmatically, when the keyboard is not shown, we can set all the app:layout_constraintBottom_toBottomOf back to parent, vice-versa.
unregistrar = KeyboardVisibilityEvent.registerEventListener(this, isOpen -> {
loginLayout.startAnimation(AnimationManager.getFade(200));
if (isOpen) {
setSoftKeyViewParams(loginLogo, R.id.guideline, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
63, 0, 63, 0);
setSoftKeyViewParams(loginFields, R.id.guideline, -1, R.id.loginLogo, null, 0.15f,
32, 0, 32, 0);
setSoftKeyViewParams(loginBtn, R.id.guideline, -1, R.id.useFingerPrintIdText, null, 0.5f,
32, 0, 32, 0);
} else {
setSoftKeyViewParams(loginLogo, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
63, 0, 63, 0);
setSoftKeyViewParams(loginFields, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.loginLogo,null, 0.15f,
32, 0, 32, 0);
setSoftKeyViewParams(loginBtn, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.useFingerPrintIdText,null, 0.25f,
32, 0, 32, 0);
}
});
Call this method:
private void setSoftKeyViewParams(View view, int bottomToBottom, int topToTop, int topToBottom, String ratio, float verticalBias,
int left, int top, int right, int bottom) {
ConstraintLayout.LayoutParams viewParams = new ConstraintLayout.LayoutParams(view.getLayoutParams().width, view.getLayoutParams().height);
viewParams.dimensionRatio = ratio;
viewParams.bottomToBottom = bottomToBottom;
viewParams.topToTop = topToTop;
viewParams.topToBottom = topToBottom;
viewParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
viewParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
viewParams.verticalBias = verticalBias;
viewParams.setMargins(Dimensions.dpToPx(left), Dimensions.dpToPx(top), Dimensions.dpToPx(right), Dimensions.dpToPx(bottom));
view.setLayoutParams(viewParams);
}
The important thing is to be sure to set the vertical bias in a way that would scale correctly when the keyboard is shown and not shown.
Many answers are right. In AndroidManifest I wrote:
<activity
android:name=".SomeActivity"
android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
android:theme="#style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" />
In my case I added a theme in styles.xml, but you can use your own:
<style name="AppTheme.NoActionBar" parent="AppTheme">
<!-- Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
I noiced that if I use full-screen theme, resizing doesn't occur:
<style name="AppTheme.FullScreenTheme" parent="AppTheme">
<!-- Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<!-- Hide StatusBar -->
<item name="android:windowFullscreen">true</item>
</style>
Also in my case adjustResize works, but adjustPan doesn't.
For full-screen layouts see a workaround in Android How to adjust layout in Full Screen Mode when softkeyboard is visible or in https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584.
Also https://medium.com/#sandeeptengale/problem-solved-3-android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32 works, but it's StatusBar is transparent, so battery, clock, Wi-Fi icons are visible.
If you create an activity with File > New > Activity > Fullscreen Activity, where in code is used:
fullscreen_content.systemUiVisibility =
View.SYSTEM_UI_FLAG_LOW_PROFILE or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
you also won't achieve a result. You can use android:fitsSystemWindows="true" in a root container, but StatusBar appears. So use workarounds from the first link.
You can simply set these options in the AndroidManifest.xml file.
<activity
android:name=".YourACtivityName"
android:windowSoftInputMode="stateVisible|adjustResize">
The use of adjustPan is not recommended by Google because the user may need to close the keyboard to see all the input fields.
More info: Android App Manifest
For me it worked with this line of code:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Just put it into onCreate method.
Best!
Add this line into Manifiest File:
android:windowSoftInputMode="adjustResize"
In Kotlin or in ConstraintLayout you just add :
android:windowSoftInputMode="stateHidden|adjustResize"
OR
android:windowSoftInputMode="stateVisible|adjustResize"
Which state you need after activity launch, you can set from manifest.
in your AndroidManifest.xml like this:
<activity
android:name=".ActivityName"
android:windowSoftInputMode="stateHidden|adjustResize"
/>
Easy way in kotlin
In your fragment
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
In your layout :
android:fitsSystemWindows="true"
In my case it helped.
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main2"
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"
android:orientation="vertical"
tools:context="com.livewallpaper.profileview.loginact.Main2Activity">
<TextView
android:layout_weight="1"
android:layout_width="match_parent"
android:text="Title"
android:gravity="center"
android:layout_height="0dp" />
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<EditText
android:hint="enter here"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_weight="1"
android:text="signup for App"
android:gravity="bottom|center_horizontal"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
Use this in manifest file
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
Now the most important part!
Use theme like this in either Activity or Application tag.
android:theme="#style/AppTheme"
And the theme tooks like this
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
So I was missing the theme. Which made me frustrated all day.
I use this Extended class frame
And when I need to recalculate the height size onLayout I override onmeasure
and subtract keyboardHeight using getKeyboardHeight()
My create frame who needs resize with softkeyboard
SizeNotifierFrameLayout frameLayout = new SizeNotifierFrameLayout(context) {
private boolean first = true;
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
fixLayoutInternal(first);
first = false;
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - getKeyboardHeight(), MeasureSpec.EXACTLY));
}
#Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (child == actionBar) {
parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
}
return result;
}
};
SizeNotifierFrameLayout
public class SizeNotifierFrameLayout extends FrameLayout {
public interface SizeNotifierFrameLayoutDelegate {
void onSizeChanged(int keyboardHeight, boolean isWidthGreater);
}
private Rect rect = new Rect();
private Drawable backgroundDrawable;
private int keyboardHeight;
private int bottomClip;
private SizeNotifierFrameLayoutDelegate delegate;
private boolean occupyStatusBar = true;
public SizeNotifierFrameLayout(Context context) {
super(context);
setWillNotDraw(false);
}
public Drawable getBackgroundImage() {
return backgroundDrawable;
}
public void setBackgroundImage(Drawable bitmap) {
backgroundDrawable = bitmap;
invalidate();
}
public int getKeyboardHeight() {
View rootView = getRootView();
getWindowVisibleDisplayFrame(rect);
int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView);
return usableViewHeight - (rect.bottom - rect.top);
}
public void notifyHeightChanged() {
if (delegate != null) {
keyboardHeight = getKeyboardHeight();
final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y;
post(new Runnable() {
#Override
public void run() {
if (delegate != null) {
delegate.onSizeChanged(keyboardHeight, isWidthGreater);
}
}
});
}
}
public void setBottomClip(int value) {
bottomClip = value;
}
public void setDelegate(SizeNotifierFrameLayoutDelegate delegate) {
this.delegate = delegate;
}
public void setOccupyStatusBar(boolean value) {
occupyStatusBar = value;
}
protected boolean isActionBarVisible() {
return true;
}
#Override
protected void onDraw(Canvas canvas) {
if (backgroundDrawable != null) {
if (backgroundDrawable instanceof ColorDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
}
backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
backgroundDrawable.draw(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (backgroundDrawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) backgroundDrawable;
if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
canvas.save();
float scale = 2.0f / AndroidUtilities.density;
canvas.scale(scale, scale);
backgroundDrawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getMeasuredHeight() / scale));
backgroundDrawable.draw(canvas);
canvas.restore();
} else {
int actionBarHeight =
(isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int viewHeight = getMeasuredHeight() - actionBarHeight;
float scaleX = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth();
float scaleY = (float) (viewHeight + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight();
float scale = scaleX < scaleY ? scaleY : scaleX;
int width = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale);
int height = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale);
int x = (getMeasuredWidth() - width) / 2;
int y = (viewHeight - height + keyboardHeight) / 2 + actionBarHeight;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
backgroundDrawable.setBounds(x, y, x + width, y + height);
backgroundDrawable.draw(canvas);
canvas.restore();
}
}
} else {
super.onDraw(canvas);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
notifyHeightChanged();
}
}
This code works for me. When keyboard appears, you can scroll screen
In AndroidManifest.xml
<activity android:name=".signup.screen_2.SignUpNameAndPasswordActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
</activity>
activity_sign_up.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".signup.screen_2.SignUpNameAndPasswordActivity">
<LinearLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_marginTop="#dimen/dp_24"
android:layout_marginStart="#dimen/dp_24"
android:layout_marginEnd="#dimen/dp_24"
android:id="#+id/lin_name_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="sans-serif-medium"
android:text="#string/name_and_password"
android:textColor="#color/colorBlack"
android:layout_marginTop="#dimen/dp_5"
android:textSize="#dimen/ts_16"/>
<EditText
android:id="#+id/edit_full_name"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
app:layout_constraintTop_toTopOf="parent"
android:hint="#string/email_address_hint"
android:inputType="textPersonName"
android:imeOptions="flagNoFullscreen"
android:textSize="#dimen/ts_15"
android:background="#drawable/rounded_border_edittext"
android:layout_marginTop="#dimen/dp_15"
android:paddingStart="#dimen/dp_8"
android:paddingEnd="#dimen/dp_8"
android:maxLength="100"
android:maxLines="1"/>
<EditText
android:id="#+id/edit_password"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
app:layout_constraintTop_toTopOf="parent"
android:hint="#string/password"
android:inputType="textPassword"
android:imeOptions="flagNoFullscreen"
android:textSize="#dimen/ts_15"
android:background="#drawable/rounded_border_edittext"
android:layout_marginTop="#dimen/dp_15"
android:paddingStart="#dimen/dp_8"
android:paddingEnd="#dimen/dp_8"
android:maxLength="100"
android:maxLines="1"/>
<TextView
android:id="#+id/btn_continue_and_sync_contacts"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="#dimen/dp_15"
android:background="#drawable/btn_blue_selector"
android:enabled="false"
android:text="#string/continue_and_sync_contacts"
android:textColor="#color/colorWhite"
android:textSize="#dimen/ts_15"
android:textStyle="bold"/>
<TextView
android:id="#+id/btn_continue_without_syncing_contacts"
android:layout_width="match_parent"
android:layout_height="#dimen/dp_44"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="#dimen/dp_10"
android:enabled="false"
android:text="#string/continue_without_syncing_contacts"
android:textColor="#color/colorBlue"
android:textSize="#dimen/ts_15"
android:textStyle="bold"/>
</LinearLayout>
<!--RelativeLayout is scaled when keyboard appears-->
<RelativeLayout
android:layout_marginStart="#dimen/dp_24"
android:layout_marginEnd="#dimen/dp_24"
android:layout_marginBottom="#dimen/dp_20"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_learn_more_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_gravity="center_horizontal"
android:text="#string/learn_more_syncing_contacts"
android:textColor="#color/black_alpha_70"
android:gravity="center"
android:layout_marginBottom="1dp"
android:textSize="#dimen/ts_13"/>
<TextView
android:id="#+id/tv_learn_more_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_gravity="center_horizontal"
android:text="#string/learn_more"
android:fontFamily="sans-serif-medium"
android:textColor="#color/black_alpha_70"
android:textSize="#dimen/ts_13"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
rounded_border_edittext.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
<solid android:color="#F6F6F6"/>
<corners android:radius="3dp"/>
<stroke
android:width="1dp"
android:color="#color/red"/>
</shape>
</item>
<item android:state_activated="false">
<shape android:shape="rectangle">
<solid android:color="#F6F6F6"/>
<corners android:radius="3dp"/>
<stroke
android:width="1dp"
android:color="#color/colorGray"/>
</shape>
</item>
</selector>
btn_blue_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="#color/colorBlueLight"/>
<stroke android:width="1dp" android:color="#color/colorBlueLight"/>
</shape>
</item>
<item android:state_enabled="true">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="#color/colorBlue"/>
<stroke android:width="1dp" android:color="#color/colorBlue"/>
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="#color/colorBlueAlpha"/>
<stroke android:width="0dp" android:color="#color/colorBlueAlpha"/>
</shape>
</item>
</selector>
In my case only this solution worked:
In Manifest:
<activity
android:name=".TTSpeech"
android:windowSoftInputMode="adjustPan"
android:exported="false" />
In Activity call
clearFocus();
on edittext.
In Xamarin register below code in your activity
WindowSoftInputMode = Android.Views.SoftInput.AdjustResize | Android.Views.SoftInput.AdjustPan
I used a Relative Layout if you're using Constraint Layout, the above code will work code below

Android java android.support.design.widget.TextInputLayout with clear button

Is there any way to get something like that, plus the button to clean/delete the text when it contains something?
<android.support.design.widget.TextInputLayout
android:id="#+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Inserisci Username">
<EditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username"
android:inputType="text" />
</android.support.design.widget.TextInputLayout>
I know it's been a while, but maybe it helps someone.
If you use Material components, you can use app:endIconMode="clear_text", for example:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/key_word_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintEnabled="true"
android:hint="#string/key_word"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_gravity="center_horizontal"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/key_word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
This will bring up the little X button as soon as the text has been entered, and will automatically work as expected.
Read more options at Text fields
To clear the text from edit text
#Override
public void onClick(View v) {
editText.getText().clear();
//or you can use editText.setText("");
}
To put the button inside edittext just make the custom layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/oval"
android:layout_centerInParent="true"
>
<android.support.design.widget.TextInputLayout
android:id="#+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_toLeftOf="#+id/id_search_button"
android:hint="Inserisci Username">
<EditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="username"
android:background="#android:color/transparent"
android:inputType="text" />
</android.support.design.widget.TextInputLayout>
<ImageButton android:id="#+id/id_search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:background="#drawable/ic_clear_black"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</RelativeLayout>
drawable oval
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#ffffff"/>
<stroke android:width="2px" android:color="#ff00ffff"/>
<corners android:radius="24dp" />
</shape>
To hide focus of the editText when app starts
add these lines inside activity tag of your class name in manifest file
<activity
android:name=".yourActivityName"
android:windowSoftInputMode="stateAlwaysHidden"
android:focusable="true"
android:focusableInTouchMode="true"
/>
You can set property of Layout like android:descendantFocusability="beforeDescendants" and android:focusableInTouchMode="true"
<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:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
xmlns:ads="http://schemas.android.com/apk/res-auto"
>
You could use onTouchEvent() for determine user touch to 'clear text' icon
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
final int x = (int) event.getX();
final int y = (int) event.getY();
if (x >= (this.getRight() - drawableClearText.getBounds().width()) && x <= (this.getRight() - this.getPaddingRight())
&& y >= this.getPaddingTop() && y <= (this.getHeight() - this.getPaddingBottom())) {
this.setText("");
event.setAction(MotionEvent.ACTION_CANCEL);
}
}
return super.onTouchEvent(event);
}
To manage the icon states(visible, invisible) you may use TextViewCompat.setCompoundDrawablesRelative(your_edit_text, compounds[0], compounds[1], drawableClearText, compounds[3])

Items doesn't fill space

I have a RecyclerView. When you look at the picture, I have the Problem, that the Items of the RecyclerView won't fill the full space of the screen. (I mean the space between the item_note and the screen edge...
Here is my main_activity.XML:
<android.support.v7.widget.RecyclerView
android:id="#+id/rvNoteList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
Here is my item_layout.XM:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:background="#drawable/note_bg">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="9"
android:orientation="vertical">
<TextView
android:id="#+id/tvTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Title"
android:textStyle="bold"
android:textSize="18sp" />
<TextView
android:id="#+id/tvContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Text for Content" />
</LinearLayout>
Here is how I set the Layout in MainActivity.java:
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
recyclerView.setItemAnimator(new DefaultItemAnimator());
EDIT:
click to see
EDIT 2:
click to see
EDIT 3:
Adapter:
adapter = new FirestoreRecyclerAdapter<Note, NoteViewHolder>(response) {
#Override
protected void onBindViewHolder(NoteViewHolder holder, int position, Note model) {
final Note note = notesList.get(position);
holder.title.setText(note.getTitle());
holder.content.setText(note.getContent());
}
#Override
public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note, parent, false);
return new NoteViewHolder(view);
}
#Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
};
EDIT 4:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#CABBBBBB"/>
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/white"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
If you don't want gaps as you've described, you probably don't want to be using StaggeredGridLayoutManager, since it will try to add gaps at the end of some rows to create a jagged edge effect. See https://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager.html for more details.
For evenly spaced items, you should use GridLayoutManager. So, try changing
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
To
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
See https://developer.android.com/reference/android/support/v7/widget/GridLayoutManager.html#GridLayoutManager(android.content.Context,%20int) for more details on how to use GridLayoutManager.
Alternate Solution 1
If you want to stick with the StaggeredGridLayoutManager, you can try setting its gap handling strategy to GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS like so:
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
recyclerView.setLayoutManager(layoutManager);
Alternate Solution 2
Try changing the contents of your item_layout.xml to:
<?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="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:background="#drawable/note_bg">
<TextView
android:id="#+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Title"
android:textStyle="bold"
android:textSize="18sp" />
<TextView
android:id="#+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Text for Content" />
</LinearLayout>
Edit
Using Alternate Solution 2 and StaggeredGridLayoutManager, I was able to get the following result (using the same text in your items):

Android: Adding a border and rounding to recyclerView items

I have a recyclerView currently set up to add a drop shadow to the bottom of each item with spacing which works well. I want to add a thin gray border around each item as well as a soft rounding if possible. Code so far:
public class VerticalSpaceItemDecorator extends RecyclerView.ItemDecoration {
private final int verticalSpaceHeight;
public VerticalSpaceItemDecorator(int verticalSpaceHeight) {
this.verticalSpaceHeight = verticalSpaceHeight;
}
#Override
public void getItemOffsets(Rect outRect,
View view,
RecyclerView parent,
RecyclerView.State state) {
// 1. Determine whether to add a spacing decorator
if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
// 2. Set the bottom offset to the specified height
outRect.bottom = verticalSpaceHeight;
}
}
}
public class ShadowVerticalSpaceItemDecorator extends RecyclerView.ItemDecoration {
private Drawable divider;
public ShadowVerticalSpaceItemDecorator(Context context) {
// Use the default style divider
final TypedArray styledAttributes = context.obtainStyledAttributes(
new int[] { android.R.attr.listDivider });
this.divider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
public ShadowVerticalSpaceItemDecorator(Context context, int resId) {
// Use a custom divider specified by a drawable
this.divider = ContextCompat.getDrawable(context, resId);
}
#Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
// 1. Get the parent (RecyclerView) padding
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
// 2. Iterate items of the RecyclerView
for (int childIdx = 0; childIdx < parent.getChildCount(); childIdx++) {
// 3. Get the item
View item = parent.getChildAt(childIdx);
// 4. Determine the item's top and bottom with the divider
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) item.getLayoutParams();
int top = item.getBottom() + params.bottomMargin;
int bottom = top + divider.getIntrinsicHeight();
// 5. Set the divider's bounds
this.divider.setBounds(left, top, right, bottom);
// 6. Draw the divider
this.divider.draw(c);
}
}
}
Custom layout of recyclerView items:
<?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="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/textView_title"
style="#style/AudioFileInfoOverlayText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView"
android:layout_alignLeft="#+id/imageView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignStart="#+id/imageView"
android:layout_gravity="left"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="TextView"
android:textColor="#android:color/white"
android:textSize="22sp" />
<TextView
android:id="#+id/textView_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignStart="#+id/textView_title"
android:layout_below="#+id/imageView"
android:layout_marginTop="12dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="TextView" />
<Button
android:id="#+id/button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView_info"
android:layout_marginBottom="5pt"
android:layout_marginRight="5pt"
android:background="#drawable/circle_button"
android:text="One"
android:textColor="#android:color/white" />
<Button
android:id="#+id/button_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_below="#+id/textView_info"
android:layout_marginBottom="5pt"
android:layout_marginLeft="5pt"
android:background="#drawable/circle_button"
android:backgroundTint="?android:attr/colorControlHighlight"
android:text="Two"
android:textColor="#android:color/white" />
</RelativeLayout>
</LinearLayout>
drop_shadow code:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="4dp" />
<solid android:color="#color/darkGray" />
<corners android:topLeftRadius="0dp" android:topRightRadius="0dp"
android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp"/>
</shape>
Border:
<?xml version="1.0" encoding="UTF-8"?>
<stroke android:width="3dp"
android:color="#color/gray"
/>
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
/>
<corners android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
Create Xml on Drawable folder named border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="#color/colorAccent" android:width="1dp"/>
<corners android:radius="5dp" />
</shape>
then after change background of RelativeLayout
<?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="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/border"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/textView_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView"
android:layout_alignLeft="#+id/imageView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignStart="#+id/imageView"
android:layout_gravity="left"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="TextView"
android:textColor="#android:color/white"
android:textSize="22sp" />
<TextView
android:id="#+id/textView_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignStart="#+id/textView_title"
android:layout_below="#+id/imageView"
android:layout_marginTop="12dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="TextView" />
<Button
android:id="#+id/button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView_info"
android:layout_marginBottom="5pt"
android:layout_marginRight="5pt"
android:text="One"
android:textColor="#android:color/white" />
<Button
android:id="#+id/button_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_below="#+id/textView_info"
android:layout_marginBottom="5pt"
android:layout_marginLeft="5pt"
android:backgroundTint="?android:attr/colorControlHighlight"
android:text="Two"
android:textColor="#android:color/white" />
</RelativeLayout>
</LinearLayout>
If you want to bold the border then <stroke android:color="#color/colorAccent" android:width="5dp"/>

Adding ripple effect for View in onClick

Hello I am trying to add a ripple effect onClick method for View, but this one no working. All my items having an ID, but I don't know how to call it
Here is a code.
#Override
public void onClick(View v) {
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
v.setBackgroundResource(backgroundResource);
switch (v.getId()) {
case ACTION_PLAY_ID:
Log.d(MainActivity.TAG, getString(R.string.detail_action_play));
v.setBackgroundResource(backgroundResource);
Intent intent = new Intent(getActivity(), PlayerActivity.class);
intent.putExtra(Video.VIDEO_TAG, videoModel);
startActivity(intent);
break;
case ACTION_BOOKMARK_ID:
if (bookmarked) {
v.setBackgroundResource(backgroundResource);
deleteFromBookmarks();
((ImageView) v).setImageDrawable(res.getDrawable(R.drawable.star_outline));
} else {
v.setBackgroundResource(backgroundResource);
addToBookmarks();
((ImageView) v).setImageDrawable(res.getDrawable(R.drawable.star));
}
break;
case ACTION_REMINDER_ID:
if (!isReminderSet) {
createReminderDialog((ImageView) v);
} else {
cancelReminder(liveTvProgram.getProgramId());
((ImageView) v).setImageDrawable(res.getDrawable(R.drawable.alarm));
}
break;
}
}
For Lubomir
i have something like this but not working too:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.item_detail, container, false);
ButterKnife.bind(this, view);
View myView = view.findViewById(R.id.actions_container);
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
myView.setBackgroundResource(backgroundResource);
loadImage();
init();
return view;
}
ImageViews(actionbuttons) is creating in java for LinearLayout actions_container
<?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">
<ImageView
android:id="#+id/header_image"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="#dimen/detail_image_1_state"
android:elevation="8dp"/>
<RelativeLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="#dimen/detail_bottom_margin"
android:layout_marginTop="#dimen/detail_top_margin"
android:background="#color/primary_color">
<LinearLayout
android:id="#+id/actions_container"
android:layout_width="match_parent"
android:layout_height="#dimen/detail_actions_height"
android:layout_alignParentTop="true"
android:background="#drawable/ripple_effect_image"
android:elevation="2dp"
android:orientation="horizontal"
android:paddingLeft="300dp"
android:paddingStart="300dp"/>
<LinearLayout
android:id="#+id/content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/actions_container"
android:orientation="vertical"
android:paddingLeft="300dp"
android:paddingStart="300dp">
<TextView
android:id="#+id/title"
style="#style/TextTitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/subtitle"
style="#style/TextSubtitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/duration"
style="#style/TextSubtitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/season"
style="#style/TextDescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/episode"
style="#style/TextDescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/description"
style="#style/TextDescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="7"/>
</LinearLayout>
<FrameLayout
android:id="#+id/recommended_frame"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentBottom="true">
<android.support.v17.leanback.widget.HorizontalGridView
android:id="#+id/recommendation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingLeft="10dp"
android:paddingRight="10dp"/>
</FrameLayout>
<TextView
android:id="#+id/recommended_text"
style="#style/TextHeaderStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/recommended_frame"
android:text="#string/related_programs"/>
</RelativeLayout>
</RelativeLayout>
Also my xml ripple effect file is like:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/dark_primary_color">
<item>
<color android:color="#color/dark_primary_color" />
</item>
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
Clickable Views
In general, ripple effect for regular buttons will work by default in API 21 and for other touchable views, it can be achieved by specifying
android:background="?android:attr/selectableItemBackground"
In code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
View myView = findViewById(R.id.myView);
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
myView.setBackgroundResource(backgroundResource);
}
As stated in Lubomir Babev's answer, adding android:background="?android:attr/selectableItemBackground" does the trick.
However, if your view already has a background, you can use the same on the android:foreground attribute instead:
android:background="#color/anyColor"
android:foreground="?android:attr/selectableItemBackground"
android:foreground is only supported by API 23+ though.
create ripple background
view_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/blue" >
<item android:drawable="#drawable/view_normal">
</item>
</ripple>
view_noraml.xml //this is how you view appears in normal
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners
android:radius="#dimen/button_corner"/>
<solid
android:color="#android:color/transparent"/>
<stroke
android:width="0.5dp"
android:color="#color/white"/>
</shape>
now set the view_background to your view
example
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:foreground="#drawable/view_background"
android:clickable="true"
android:focusable="true"
>
<ImageView
android:id="#+id/grid_item_imageView"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="center"
android:scaleType="centerInside"
/>
</FrameLayout>
I know this is a pretty old thread but just in case the above answers didn't work, I'd recommend you to try the below code as it worked for me:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
The key thing to notice are the clickable and focusable.
The solution for this is simple easy in my side.
Here is ripple effect:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#BFB3F7">
<item android:id="#android:id/mask">
<shape android:shape="oval">
<solid android:color="#color/button_background_color" />
</shape>
</item>
</ripple>
and next on the class i need to search function
setBackground
Then i need declare a drawable item to it. something like this:
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
v.setBackground(res.getDrawable(R.drawable.ripple_effect_for_buttons));
scrollContainer(false);
} else {
v.setBackground(null);
if (recommendation.getFocusedChild() != null) {
scrollContainer(true);
}
}
}
And YUPII its working
You can add:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="#drawable/ripple"/>
In Kotlin it could be easily done with an extension functions.
fun TypedArray.use(block: TypedArray.() -> Unit) {
try {
block()
} finally {
this.recycle()
}
}
fun Context.getStyledAttributes(#StyleableRes attrs: IntArray, block: TypedArray.() -> Unit) =
this.obtainStyledAttributes(attrs).use(block)
fun View.setClickableRipple() {
val attrs = intArrayOf(R.attr.selectableItemBackground)
context.getStyledAttributes(attrs) {
val backgroundResource = getResourceId(0, 0)
setBackgroundResource(backgroundResource)
}
}

Categories

Resources