I have a recyclerview in which there is an edit text where it will hidden and opens up on click of some button.
Please refer to screen 1.
On click of reject or accept the view is displayed:
Now, my recyclerview is expanding downwards but I want it to expand upward like this:
By default, it expands downward:
I want it to expand upward like this:
Similarly, when keyboard opens up I want the whole recyclerview cell just above the keyboard like this.
By default, it does not move upward:
I want something like this:
What should be the approach for this functionality?
Do I have to do the calculations of cell height, keyboard height or is there some other method for this.
Please attach related links.
Thanks
I wrote this for my chat class you can rewrite this code snippet according to yours.
private boolean keyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");
if (keyboardUp == false) {
if (results.size() > 0)
chatList.smoothScrollToPosition(results.size()+1);
keyboardUp = true;
}
} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});
Let's divide the question into two, scroll down the RecyclerView and show the cell when the keyboard is shown.
just use the scrollToPosition(index) with to the cell index
you can just change the android:windowSoftInputMode to be adjustSize in the activity:
<activity
android:windowSoftInputMode="adjustResize"
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
or just in the fragment:
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
Related
I have a Fragment with a static top view,a static bottom view and a ViewPager2 in the middle of those 2 views.(Look for Picture1 in the link provided). I have a problem when the keyboard shows up my bottom static view moves up. I tried all of android soft input methods and some code linked with that, some other code in stackoverflow but it doesn't work.
android:windowSoftInputMode="stateAlwaysHidden|adjustPan" //does not work
What i'm trying to do is hide that bottom static view like in Picture 2:
I archived what I was looking with this code:
binding.parentConstrint.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
binding.parentConstrint.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.parentConstrint.rootView.height
val keypadHeight = screenHeight - r.bottom
if (keypadHeight > screenHeight * 0.15) {
if (!isKeyboardShowing) {
isKeyboardShowing = true
binding.bottomView.gone()
}
}else {
if (isKeyboardShowing) {
isKeyboardShowing = false
binding.bottomView.visible()
}
}
}
But this kinda refreshes my whole View when that bottom view appears and disappears and i can see that refresh happening with my eyes. Any ideas how to stop that refresh or to do this in another way?
Remove the layout listener and use:
android:windowSoftInputMode="stateHidden|adjustNothing"
Otherwise try to remove this last line too from manifest
Fragment layout
Actually the footer is set inside an activity class and the edittext is placed inside a fragment.
manifest file
<activity
android:name="HomeController"
android:label="#string/app_name"
android:windowSoftInputMode="stateHidden|adjustPan"/>
Inside my fragment class I added
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
These are the code snippet that I used, but it won't work!
Note: in Fragment UI, the whole screen has a scroll view,
Don't know why it is happening like this?Actually I don't want my footer on the keyboard's top.
Any suggestions on how to solve this behavior? And its appriciatble for the replies :)
Add this to your activity.
I did not test, but this might work. it is a bad way though(
contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect r = new Rect();
View rootView = getWindow().getDecorView().getRootView();
rootView.getWindowVisibleDisplayFrame(r);
int screenHeight = rootView.getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
//set bottom navigation(footer) bar to View.GONE
}
else {
// keyboard is closed
//set bottom navigation bar(footer) to View.VISIBLE
}
}
});
Use android:windowSoftInputMode="hidden" in your parent layout in the xml file. also in case it has layoutAbove property then try to remove it.
Try to add the following in manifest file:
android:windowSoftInputMode="stateAlwaysHidden|adjustResize"
Also remove the following from fragment:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
just like the picture, when the keyboard is show ,it hide the logo.
the question is how to listen the keyboard show/hide even? have some sample?
add this attribute to your activity in manifest
android:windowSoftInputMode="adjustResize"
Get a reference to the layout which you want to hide when keyboard pops up. You can set the visibility of that to GONE when keyboard is shown and to VISIBLE otherwise. So your task now is to detect whether the keyboard is shown or hidden. For that you can use ViewTreeObserver.OnGlobalLayoutListener().
rootView = getWindow().getDecorView().getRootView();
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
int screenHeight = rootView.getHeight();
int keyboardHeight = screenHeight - (rect.bottom - rect.top);
if(keyboardHeight > screenHeight / 3){
//hide the layout
}
else{
//show the layout
}
}
});
I have a activity that has the "adjustPan" option set and it pans my view up just fine when a EditText receives focus and the soft keyboard is shown, but my problem is that there are UI elements below my EditText that needs to be visible also when the keyboard is shown and it is not on smaller screens. Can I some how tell the view to always pan so that those UI elements are visible by linking them to the EditText or something, or do I have to take control of the panning manually and calculate height and all, or what is the good solution here?
What you can do is you can use ViewTreeObserver to pan your content l'il bit more.
I did this is my app.
int edtHeight = 0;
// llContent is the Viewgroup layout which is inside a ScrollView.
ViewTreeObserver viewTreeObserver1 = llContent.getViewTreeObserver();
viewTreeObserver1.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
// Here edtHeight will get the height of edittext as i wanted my view to scroll that much bit more
edtHeight = edtTemprature.getHeight();
ViewTreeObserver obs = llContent.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}
});
//llMain is the parent View Group of my XML layout
llMain.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
Rect r = new Rect();
// r will be populated with the coordinates of your view
// that area still visible.
llMain.getWindowVisibleDisplayFrame(r);
int heightDiff = llMain.getRootView().getHeight() - (r.bottom - r.top);
if (heightDiff > 100)
{ // if more than 100 pixels, its probably a keyboard...
if(edtTemprature.hasFocus()){
llContent.scrollTo(0, (int) (edtHeight * 1.5));
}else{
llContent.scrollTo(0, 0);
}
}
else
{
llContent.scrollTo(0, 0);
}
}
});
Use stateHidden in Android manifestfile which class you need ..
android:windowSoftInputMode="stateHidden"
or else,
In Activity,
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Im developing an app where a floating component should appear when the call is received and the component will have several buttons to perform necessary actions.
I have tried the follow.
I implemented a popup window by making the main activity translucent.when this component pops up, Im able to move it on the screen, but since the activity is translucent, im not able to perform any other activity.
here u can see the popup window, i can move it, but i cannot scroll the menudrawer in the background. How can i implement in such a way that i can perform both operations, i.e on popupwindow and the background screen.
My codes
`public class MainActivity extends Activity {
int mCurrentX;
int mCurrentY;
private float mDx;
private float mDy;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
final View cv = new View(this);
TextView tv = new TextView(this);
tv.setBackgroundColor(0xffeeeeee);
tv.setTextColor(0xff000000);
tv.setTextSize(24);
tv.setText("click me\nthen drag me");
tv.setPadding(8, 8, 8, 8);
final PopupWindow mPopup = new PopupWindow(tv, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
OnTouchListener otl = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
mDx = mCurrentX - event.getRawX();
mDy = mCurrentY - event.getRawY();
} else
if (action == MotionEvent.ACTION_MOVE) {
mCurrentX = (int) (event.getRawX() + mDx);
mCurrentY = (int) (event.getRawY() + mDy);
mPopup.update(mCurrentX, mCurrentY, -1, -1);
}
return true;
}
};
tv.setOnTouchListener(otl);
mCurrentX = 20;
mCurrentY = 50;
cv.post(new Runnable() {
#Override
public void run() {
mPopup.showAtLocation(cv, Gravity.NO_GRAVITY, mCurrentX, mCurrentY);
}
});
}
}`
manifest
`<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<activity android:name=".MainActivity"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:label="#string/app_name"
android:configChanges="orientation|screenSize"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="PopupMainActivity"
android:label="#string/app_name"
android:theme="#style/Theme.FloatingWindow.Popup"
android:configChanges="orientation|screenSize"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
android:clearTaskOnLaunch="true"
android:exported="true"
tools:ignore="ExportedActivity" />
</application>`
please help me on this. I want to implement a widget kind of component on the whole. Thanks!!
You have to start a foreground Service and draw using the WindowManager on top of everything else, manage your popup position, size, etc...
WindowManger windowManager = Context.getSystemService(Context.WINDOW_SERVICE);
You will also have to add this permission "android.permission.SYSTEM_ALERT_WINDOW" to your manifest.
A simpler solution would be to use a library called StandOut, it basically takes care of all that I mentioned above and provide extra features like:
Window decorators (titlebar, minimize/close buttons, border, resize handle)
Windows are moveable and resizable. You can bring-to-front, minimize,
and close
Minimized windows can be restored (the example APK demos this using
the notification panel)
Create multiple types of windows, and multiple windows of each type