How to get display keyboard event in android - android

I have GridView android:layout_height="match_parent" with Editboxes, in LinearLayout with fix android:layout_height.
When I touch editbox, appears keyboard.
How to change android:layout_height in LinearLayout when keyboard appears and when disappears?

Try the link below hope it may help you
http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html
http://davidwparker.com/2011/08/30/android-how-to-float-a-row-above-keyboard/
private OnSoftKeyboardListener onSoftKeyboardListener;
#Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
if (onSoftKeyboardListener != null) {
final int newSpec = MeasureSpec.getSize(heightMeasureSpec);
final int oldSpec = getMeasuredHeight();
if (oldSpec > newSpec){
onSoftKeyboardListener.onShown();
} else {
onSoftKeyboardListener.onHidden();
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public final void setOnSoftKeyboardListener(final OnSoftKeyboardListener listener) {
this.onSoftKeyboardListener = listener;
}
public interface OnSoftKeyboardListener {
public void onShown();
public void onHidden();
}

Related

Animate newly created View of unknown size

I want to animate View right after it was added to parent (something like DrawerLayout). The problem is that View has varying size, and animation target position depends on that size. Simplified sample code:
AnimatingView extends View {
public int offsetX;
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int screenWidth = MeasureSpec.getSize(widthMeasureSpec);
final int screenHeight = MeasureSpec.getSize(heightMeasureSpec);
offsetX = calculateOffset(screenWidth);
...
}
}
Code similar to this triggers the animation:
#Override
public void onClick(View v) {
AnimatingView animatingView = new AnimatingView(getContext());
parentLayout.addView(animatingView);
animatingView.animate().x(animatingView.offsetX).setDuration(500).start();
}
In this case onMeasure() happens after animate(), so animation fails. What is the correct way of doing stuff which depends on view measuring?
The simple & stupid way would be something like animateOnceAfterMeasuring() based on isInitialized flag, but I don't think it the correct way of doing this.
this should work:
AnimatingView animatingView = new AnimatingView(getContext());
parentLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
animatingView.animate().x(animatingView.offsetX).setDuration(500).start();
}
});
You can use the ViewTreeObserver for this
#Override
public void onClick(View v) {
final AnimatingView animatingView = new AnimatingView(getContext());
parentLayout.addView(animatingView);
animatingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < 16) {
animatingView.getViewTreeObserver().removeGlobalOnLayoutL‌​istener(this);
} else {
animatingView.getViewTreeObserver().removeOnGlobalLayoutList‌​ener(this);
}
animatingView.animate().x(animatingView.offsetX).setDuration(500).start();
}
});
}

How to invalidate view after it changed?

Please see this example img below first.
Sorry, my reputation is not enough, click below to see gif please
example img
Just as you see, i am using horizontalscrollview in bottom area. I can not scroll it to border when it become bigger. I can not figure out why, hope someone can help me solve this problem.
public class Rebound extends HorizontalScrollView implements View.OnClickListener {
private LinearLayout container;
private HorizontalScrollViewAdapter adapter;
private int childWidth, childHeight;
private CurrentImageChangeListener listener;
private OnItemClickListener onClickListener;
public Rebound(Context context, AttributeSet attrs) {
super(context);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
container = (LinearLayout) getChildAt(0);
}
#Override
public void invalidate() {
super.invalidate();
}
public void initDatas(HorizontalScrollViewAdapter adapter) {
this.adapter = adapter;
container = (LinearLayout) getChildAt(0);
final View view = adapter.getView(0, null, container);
container.addView(view);
calculateChildView(view);
}
private void calculateChildView(View view) {
if (childWidth == 0 && childHeight == 0) {
int w = View.MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
view.measure(w, h);
childHeight = view.getMeasuredHeight();
childWidth = view.getMeasuredWidth();
}
initChild();
}
private void initChild() {
container = (LinearLayout) getChildAt(0);
container.removeAllViews();
for (int i = 0; i < adapter.getCount(); i++) {
View view = adapter.getView(i, null, container);
view.setOnClickListener(this);
container.addView(view);
}
}
#Override
public void onClick(View v) {
}
public interface CurrentImageChangeListener {
void onCurrentImgChanged(int position, View viewIndicator);
}
public interface OnItemClickListener {
void onClick(View view, int pos);
}
public void setOnItemClickListener(OnItemClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public void setCurrentImageChangeListener(CurrentImageChangeListener listener) {
this.listener = listener;
}
}

How can i create a keyboard listener in Android?

I want to change the visibility of a particular layout when keyboard appears .How can i create a listener for that?
Make a class for Soft Keyboard Detection
public class RelativeLayoutThatDetectsSoftKeyboard extends RelativeLayout {
public RelativeLayoutThatDetectsSoftKeyboard(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public interface Listener
{
public void onSoftKeyboardShown(boolean isShowing);
}
private Listener listener;
public void setListener(Listener listener)
{
this.listener = listener;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int height = MeasureSpec.getSize(heightMeasureSpec);
Activity activity = (Activity)getContext();
Rect rect = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
int diff = (screenHeight - statusBarHeight) - height;
if (listener != null)
{
listener.onSoftKeyboardShown(diff>128); // assume all soft keyboards are at least 128 pixels high
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
Extend your activity with RelativeLayoutThatDetectsSoftKeyboard class and write below code in your activity
// To scroll layout when keyboard is visible
RelativeLayoutThatDetectsSoftKeyboard mChkKeyBoradVisibility;
mChkKeyBoradVisibility = (RelativeLayoutThatDetectsSoftKeyboard) mTabLogin_Layout.findViewById(your layout id);
mChkKeyBoradVisibility.setListener(this);

Get root dimension on profound child measure event

In the view hierarchy:
Window > ViewGroup (root) > ViewGroup[...] > View (child)
I need to know root dimension in a profound child onMeasure event.
Exemple:
#Override
protected void onMeasure(int wMS, int hMS) {
int desiredW = Math.round(rootW * factorW);
int desiredH = Math.round(rootH * factorH);
/* ... compute final dimensions ... */
setMeasuredDimension(finalW, finalH);
}
Note: At this moment, getRootView and getWindow dimentions equals to 0 because children have to setMeasuredDimention before their parents
Considering a lot of children needing this dimension, to do it:
I created an interface:
public interface OnRootSizeChanged {
public void onRootSizeChanged(int w, int h);
}
I implemented my child which now implements OnRootSizeChanged inteface:
private int rootW;
private int rootH;
#Override
public void onRootSizeChanged(int w, int h) {
rootW = w;
rootH = h;
}
I implemented root view:
#Override
protected void onMeasure(int wMS, int hMS) {
int w = MeasureSpec.getSize(wMS);
int h = MeasureSpec.getSize(hMS);
dispatchOnRootSizeChange(this, w, h);
super.onMeasure(wMS, hMS);
}
private void dispatchOnRootSizeChange(ViewGroup v, int w, int h) {
for (int i = 0, n = v.getChildCount(); i < n; i++) {
View child = v.getChildAt(i);
if (child instanceof OnRootSizeChanged)
((OnRootSizeChanged) child).onRootSizeChanged(w, h);
if (child instanceof ViewGroup)
dispatchOnRootSizeChange((ViewGroup) child, w, h);
}
}
My question is:
Have I simpler way to do this without recursivity or with better practice ?
Update: This method is invalid in case of ViewPager element in ViewGroup[...] breabcrumb. When ViewPager instantiate children pages, they have not yet received OnRootSizeChanged event so:
Children have to ask the root dimension, no the root to tell his dimension to their children
So I searched how to target root from a profound child to ask him:
getRootView() not seems targeting the view attached with setContentView()
getWindow().getDecorView() either
One possible way is:
On child:
#Override
protected void onMeasure(int wMS, int hMS) {
ViewParent parent = getParent();
while (parent instanceof RootViewClass == false)
parent = parent.getParent();
RootViewClass root = (RootViewClass) parent;
int desiredW = Math.round(root.w * factorW);
int desiredH = Math.round(root.h * factorH);
/* ... compute final dimensions ... */
setMeasuredDimension(finalW, finalH);
}
On root instance of RootViewClass:
public int w, h;
#Override
protected void onMeasure(int wMS, int hMS) {
w = MeasureSpec.getSize(wMS);
h = MeasureSpec.getSize(hMS);
super.onMeasure(wMS, hMS);
}
But with lot of children, I don't think this is a good practice. If I could find root view without use of loop.
You can forward the parent's size by storing those values in the onMeasure() method as you receive them and then letting the children access the values in their onMeasure() method through the Context reference:
// simple interface
public interface ParentRef {
void YourViewGroup getRoot();
}
// the Activity implements the interface above
public class YourActivity extends Activity implements ParentRef {
private YourViewGroup mRoot;
//in onCreate initialize the mRoot reference
#Override
public YourViewGroup getRoot() {
return mRoot;
}
//... rest of the Activity
}
// the custom ViewGroup will store the dimensions:
//fields in the root view
private int mCurWidth;
private int mCurHeight;
#Override
protected void onMeasure(int wMS, int hMS) {
int w = MeasureSpec.getSize(wMS);
int h = MeasureSpec.getSize(hMS);
mCurWidth = w;
mCurHeight = h;
// now as the children are measured they can see the values above
super.onMeasure(wMS, hMS);
}
public int getStoredWidth() {
return mCurWidth;
}
public int getStoredHeight() {
return mCurHeight;
}
// in the children's onMeasure simply do:
#Override
protected void onMeasure(int wMS, int hMS) {
final YourViewGroup root = ((ParentRef) getContext()).getRoot();
//width root.getStoredWidth()
// height root.getStoredHeight()
/* ... compute final dimensions ... */
setMeasuredDimension(finalW, finalH);
}
You can use a ViewTreeObserver (http://developer.android.com/reference/android/view/ViewTreeObserver.html)
//...get your view, than attach a viewTreeObserver on it!
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//misure the view here, like view.getHeight()
}
});

Android transfer animation of view in custom viewgroup

I want animation like expanding of the photos when I click folder of photos at gallery, like in this video about Android gallery.
i have two views in same custom viewgroup
view1 is in 0,0
view2 is in 100,100
since click "start" view1 will move to 100,0 and view2 will move to 0,100
My solution so far:
I use timer for refresh layout with new position by requestlayout.
the views' position will refresh by onLayout:
It works but it's not a native function and it is very slow with 100 views moving at same time.
Full code:
private class MyViewGroup extends ViewGroup{
View view1,view2;
Button btn;
public MyViewGroup(Context context) {
super(context);
view1=new View(context);
view1.setBackgroundColor(Color.RED);
this.addView(view1);
view2=new View(context);
view2.setBackgroundColor(Color.BLUE);
this.addView(view2);
btn=new Button(context);
btn.setText("start");
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
xLayout=0;
handler.sendEmptyMessage(0);
}
});
this.addView(btn);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
int h= MeasureSpec.getSize(heightMeasureSpec);
int widthSpec = MeasureSpec.makeMeasureSpec(50, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(50, MeasureSpec.EXACTLY);
view1.measure(widthSpec,heightSpec);
view2.measure(widthSpec,heightSpec);
btn.measure(widthSpec,heightSpec);
this.setMeasuredDimension(w, h);
}
private int xLayout=0;
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
view1.layout(xLayout,0,xLayout+50,50);
view2.layout(100-xLayout,100,150-xLayout,150);
btn.layout(0,200,50,250);
}
private void startAnimation(){
Timer timer = new Timer() ;
timer.schedule(new TimerTask(){
#Override
public void run() {
if(xLayout<100){
handler.sendEmptyMessage(0);
}
this.cancel();
}
},5);
}
private Handler handler=new Handler(){
#Override
public void handleMessage(Message msg) {
xLayout=xLayout+20;
view1.requestLayout();
startAnimation();
}
} ;
}
http://android-developers.blogspot.fr/2011/05/introducing-viewpropertyanimator.html
myView.animate().x(500).y(500);
we can use "LayoutTransition" as
final LayoutTransition transitioner = new LayoutTransition();
myViewGroup.setLayoutTransition(transitioner);
and when we click "start" addview
full code
private class MyViewGroup extends ViewGroup{
View view1,view2;
Button btn;
public MyViewGroup(final Context context) {
super(context);
view1=new View(context);
view1.setBackgroundColor(Color.RED);
this.addView(view1);
view2=new View(context);
view2.setBackgroundColor(Color.BLUE);
this.addView(view2);
btn=new Button(context);
btn.setText("start");
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
xLayout+=100;
MyViewGroup.this.addView(new View(context));
}
});
this.addView(btn);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
int h= MeasureSpec.getSize(heightMeasureSpec);
int widthSpec = MeasureSpec.makeMeasureSpec(50, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(50, MeasureSpec.EXACTLY);
view1.measure(widthSpec,heightSpec);
view2.measure(widthSpec,heightSpec);
btn.measure(widthSpec,heightSpec);
this.setMeasuredDimension(w, h);
}
private int xLayout=0;
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
view1.layout(xLayout,0,xLayout+50,50);
view2.layout(100-xLayout,100,150-xLayout,150);
btn.layout(0,200,50,250);
}
}

Categories

Resources