How to design a component in Android such as, for instance in the below image, when click on the "Select a session" button, a form filled in will appear below, and if you click again, such form will disappear?
I have just able to pop up a dialog when clicking on the component, however, what I want is to let the component appear right below the component like showing in the image.
Below is the link of how such a component looks like.
All of your links, tutorials or advice are welcome!
From the comments i got that you want to display a popup when an item is clicked but on that position.
Following code example will help. When you click on text View, it will show a popup at position where we have text View in the view
Hoping that will help.
textView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
// textView.setText("Touch coordinates : " +
// String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
showDialog(event.getX(),event.getY());
}
return true;
}
});
}
public void showDialog(float x, float y)
{
Dialog dialog;
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
dialog = builder.create();
dialog.setTitle("my dialog");
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();
//wmlp.gravity = Gravity.TOP | Gravity.LEFT;
wmlp.x = (int) x; //x position
wmlp.y = (int) y; //y position
dialog.show();
}
What i got, the popup is in the middle because the text View is also in the middle
Related
I am using popup window in my app. I want to dismiss the window when user touch outside the window. I have written the below code for the same and its working. But the issue is I have a scrollview inside my window when I tried to scroll it window itself is canceling. How can i prevent that?
mInflater = (LayoutInflater) getActivity()
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View layout = mInflater.inflate(R.layout.help_popup,
null);
mHelpPopup = new PopupWindow(layout, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, true);
mHelpPopup.setOutsideTouchable(true);
mHelpPopup.setTouchable(true);
mHelpPopup.setBackgroundDrawable(new BitmapDrawable());
mHelpPopup.setTouchInterceptor(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Logger.get().d("POPUP_WINDOW", "v: " + v.getTag() + " | event: " + event.getAction());
mHelpPopup.dismiss();
return true;
}
});
mHelpPopup.showAtLocation(layout, Gravity.CLIP_VERTICAL, (int) helpTxtView.getX(), (int) helpTxtView.getY());
I could find out the answer. It was because of touchinterceptor. when i removed that listener it is working fine.
I am new in android. Here is my question.
Is there pop up window can be moved in android? How to implement a popup window or other dialog that can be drugged. And can this pop up window not block other windows? When it pops up, I can still use other functions in main window.
Thank you in advance
Use PopupWindow Class for this purpose refer the following link:
http://www.mobilemancer.com/2011/01/08/popup-window-in-android/
here is sample code from my work , I make some comment to declare how its work
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// your custom view
View popView = inflater.inflate(R.layout.pop_view, null);
// initialise your pop window
// take custom view , with specific width , height
PopupWindow popupWindow = new PopupWindow(popView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, true);
ImageView imageview = (ImageView) popView.findViewById(R.id.imageview);
Button dismiss = (Button) popView.findViewById(R.id.disbutton);
imageview.setImageURI(imagePath);
// button used to open pop window
popupWindow.showAsDropDown(ChooseFile, 50, -30);
// here is the part related to move popwindow
popView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
int orgX = 0, orgY = 0;
int offsetX, offsetY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
orgX = (int) event.getRawX();
orgY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
offsetX = (int) event.getRawX() - orgX;
offsetY = (int) event.getRawY() - orgY;
// update popwindow postion , -1 set for width & height to make it fixed not changed
popupWindow.update(offsetX, offsetY, -1, -1);
break;
}
return true;
}
});
dismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// if you want dismiss your pop window
popupWindow.dismiss();
}
});
}
I have implemented a custom dialog for my application. I want to implement that when the user clicks outside the dialog, the dialog will be dismissed.
What do I have to do for this?
You can use dialog.setCanceledOnTouchOutside(true); which will close the dialog if you touch outside of the dialog.
Something like,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Or if your Dialog in non-model then,
1 - Set the flag-FLAG_NOT_TOUCH_MODAL for your dialog's window attribute
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - Add another flag to windows properties,, FLAG_WATCH_OUTSIDE_TOUCH - this one is for dialog to receive touch event outside its visible region.
3 - Override onTouchEvent() of dialog and check for action type. if the action type is
'MotionEvent.ACTION_OUTSIDE' means, user is interacting outside the dialog region. So in this case, you can dimiss your dialog or decide what you wanted to perform.
view plainprint?
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
this.dismiss();
}
return false;
}
For more info look at How to dismiss a custom dialog based on touch points? and
How to dismiss your non-modal dialog, when touched outside dialog region
Simply use
dialog.setCanceledOnTouchOutside(true);
You can use this implementation of onTouchEvent. It prevent from reacting underneath activity to the touch event (as mentioned howettl).
#Override
public boolean onTouchEvent ( MotionEvent event ) {
// I only care if the event is an UP action
if ( event.getAction () == MotionEvent.ACTION_UP ) {
// create a rect for storing the window rect
Rect r = new Rect ( 0, 0, 0, 0 );
// retrieve the windows rect
this.getWindow ().getDecorView ().getHitRect ( r );
// check if the event position is inside the window rect
boolean intersects = r.contains ( (int) event.getX (), (int) event.getY () );
// if the event is not inside then we can close the activity
if ( !intersects ) {
// close the activity
this.finish ();
// notify that we consumed this event
return true;
}
}
// let the system handle the event
return super.onTouchEvent ( event );
}
Source: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html
Or, if you're customizing the dialog using a theme defined in your style xml, put this line in your theme:
<item name="android:windowCloseOnTouchOutside">true</item>
This method should completely avoid activities below the grey area retrieving click events.
Remove this line if you have it:
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Put this on your activity created
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
then override the touch event with this
#Override
public boolean onTouchEvent(MotionEvent ev)
{
if(MotionEvent.ACTION_DOWN == ev.getAction())
{
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// You have clicked the grey area
displayYourDialog();
return false; // stop activity closing
}
}
// Touch events inside are fine.
return super.onTouchEvent(ev);
}
dialog.setCanceledOnTouchOutside(true);
to close dialog on touch outside.
And if you don't want to close on touch outside, use the code below:
dialog.setCanceledOnTouchOutside(false);
You can try this :-
AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);
or
alertDialog.setCancelable(true);
And if you have a AlterDialog.Builder Then you can try this:-
alertDialogBuilder.setCancelable(true);
This code is use for when use click on dialogbox that time hidesoftinput and when user click outer side of dialogbox that time both softinput and dialogbox are close.
dialog = new Dialog(act) {
#Override
public boolean onTouchEvent(MotionEvent event) {
// Tap anywhere to close dialog.
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) event.getX(),
(int) event.getY())) {
// You have clicked the grey area
InputMethodManager inputMethodManager = (InputMethodManager) act
.getSystemService(act.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(dialog
.getCurrentFocus().getWindowToken(), 0);
dialog.dismiss();
// stop activity closing
} else {
InputMethodManager inputMethodManager = (InputMethodManager) act
.getSystemService(act.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(dialog
.getCurrentFocus().getWindowToken(), 0);
}
return true;
}
};
Another solution, this code was taken from android source code of Window
You should just add these Two methods to your dialog source code.
#Override
public boolean onTouchEvent(MotionEvent event) {
if (isShowing() && (event.getAction() == MotionEvent.ACTION_DOWN
&& isOutOfBounds(getContext(), event) && getWindow().peekDecorView() != null)) {
hide();
}
return false;
}
private boolean isOutOfBounds(Context context, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
final View decorView = getWindow().getDecorView();
return (x < -slop) || (y < -slop)
|| (x > (decorView.getWidth()+slop))
|| (y > (decorView.getHeight()+slop));
}
This solution doesnt have this problem :
This works great except that the activity underneath also reacts to the touch event. Is there some way to prevent this? – howettl
Following has worked for me:
myDialog.setCanceledOnTouchOutside(true);
Call dialog.setCancelable(false); from your activity/fragment.
You can make a background occupying all the screen size transparent and listen to the onClick event to dismiss it.
I tried some answers still I faced a problem like when I press outside the dialog dialog was hiding but a dimmed view was showing, and pressing again would go to the parent activity. But actually I wanted to go the parent activity after first click.
So what I did was
dialog.setOnCancelListener(this);
and changed my activity to implement DialogInterface.OnCancelListener with
#Override
public void onCancel(DialogInterface dialog) {
finish();
}
And boom, it worked.
Here is the code
dialog.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(MotionEvent.ACTION_DOWN == ev.getAction())
{
Rect dialogBounds = new Rect();
dialog. getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// You have clicked the grey area
UiUtils.hideKeyboard2(getActivity());
return false; // stop activity closing
}
}
getActivity().dispatchTouchEvent(ev);
return false;
}
});
Try this one . you can hide the keyboard when you touch outside
I have a listview and when the user presses a button I want to gather the coordinates of the button and place an edittext that I inflate right over top of it on the screen. When the user clicks anywhere else on the screen the edittext will disappear and it will fire a method that uses the data the user entered into the box. How would I go about doing something like this? I would like something similar to QuickActions, but not quite as intrusive. Could someone point me in the direction of at least how to go about getting the button coordinates?
Ok, so here is how i've been able to achieve what i'm looking to do. Is it possible to dynamically place a PopupWindow without having to mess with adjusting margins etc.
public void showPopup(View view, View parentView, final int getId, String getLbs){
int pWidth = 100;
int pHeight = 80;
int vHeight = parentView.getHeight(); //The listview rows height.
int[] location = new int[2];
view.getLocationOnScreen(location);
final View pView = inflater.inflate(R.layout.list_popup, null, false);
final PopupWindow pw = new PopupWindow(pView, pWidth, pHeight, false);
pw.setTouchable(true);
pw.setFocusable(true);
pw.setOutsideTouchable(true);
pw.setBackgroundDrawable(new BitmapDrawable());
pw.showAtLocation(view, Gravity.NO_GRAVITY, location[0]-(pWidth/4), location[1]+vHeight);
final EditText input = (EditText)pView.findViewById(R.id.Input);
input.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
Log.i("Focus", "Focus Changed");
if (hasFocus) {
//Shows the keyboard when the EditText is focused.
InputMethodManager inputMgr = (InputMethodManager)RecipeGrainActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
inputMgr.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
}
}
});
input.setText("");
input.requestFocus();
Log.i("Input Has Focus", "" + input.hasFocus());
pw.setOnDismissListener(new OnDismissListener(){
#Override
public void onDismiss() {
changeWeight(getId, Double.parseDouble(input.getText().toString()));
Log.i("View Dismiss", "View Dismissed");
}
});
pw.setTouchInterceptor(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Log.i("Background", "Back Touched");
pw.dismiss();
return true;
}
return false;
}
});
}
The pWidth and pHeight are the size of the PopupWindow I chose and the vHeight is the height of the main parent view that I collected from the onCreate context. Keep in mind this is not polished code. I still need to add a few things like animate in and out as well as a nice little arrow or something to show what the window is being associated with. The setBackgroundDrawable is very important and if you don't use it you won't be able to click outside the box to close it.
Right now, its weird. I have to click twice outside the box to close the window. The first click just seems to highlight my textbox and the second click actually closes it out. Anyone have any idea why that might be happening?
Messy, depending on your View hierarchy. The getLeft() method (along with getRight, getTop and getBottom) are all relative to the control's View parent. Take a look at getLocationOnScreen and see if it does what you want.
I have a dialog:
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.location_dialog);
dialog.setTitle("My dialog");
dialog.setMessage("My dialog's content");
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
dialog.show();
I want to be able to detect touches over and outside the dialog box's lines.
I can easily detect any touches outside the dialog box area with the build-in method
dialog.setCanceledOnTouchOutside(true);
But how can I detect the touches inside this area?
Create an extension of Dialog and override necessary method: dispatchTouchEvent or onTouchEvent (From docs: This is most useful to process touch events that happen outside of your window bounds, where there is no view to receive it.)
Updated:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
Log.d("test", "inside");
} else {
Log.d("test", "outside");
}
return super.dispatchTouchEvent(ev);
}