I'm trying to implement long press image preview like in Instagram.
My application is having a catalog which contains images where when I click on any image, its preview should appear and close after releasing like in Instagram while checking grid for posts (You can have a zoomed Item Layout with Comment and Heart Option).
Check Image 1 : That will be the list.
Check Image 2 : That is what I want on clicking list item.
I tried achieving the same by Enlarge a view using a zoom animation but it applies good on Image not the whole Item Layout.
public void show(Context context, ImageView source) {
BitmapDrawable background = ImagePreviewerUtils.getBlurredScreenDrawable(context, source.getRootView());
View dialogView = LayoutInflater.from(context).inflate(R.layout.view_image_previewer, null);
ImageView imageView = (ImageView) dialogView.findViewById(R.id.previewer_image);
Drawable copy = source.getDrawable().getConstantState().newDrawable();
imageView.setImageDrawable(copy);
final Dialog dialog = new Dialog(context, R.style.ImagePreviewerTheme);
dialog.getWindow().setBackgroundDrawable(background);
dialog.setContentView(dialogView);//You can set your custem view here
dialog.show();
source.setOnTouchListener(new View.OnTouchListener() {
#Override public boolean onTouch(View v, MotionEvent event) {
if (dialog.isShowing()) {
v.getParent().requestDisallowInterceptTouchEvent(true);
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
v.getParent().requestDisallowInterceptTouchEvent(false);
dialog.dismiss();
return true;
}
}
return false;
}
});
}
Note: Modify dialog contentview (layout) as per your need
Use this zoom layout with transparent dialog theme Zoom Layout
I am building android Application in which i have embedded a searchview below toolbar. See Screenshot. But when i click on the search icon my keyboard appears but when i click close icon of searchview, keyboard does not disappear. Close listener is not working and action expand or collapse listener can not be used because it is not a menuitem. So how should i disappear the keyboard. Please guide.
simpleSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
#Override
public boolean onClose() {
hideKeyboard(getActivity());
return false;
}
});
You can do this by getting a reference to the [x] button, then setting an onClick listener on it. In the onClickListener, you could add logic to hide the keyboard.
The code below was obtained from this answer
// Catch event on [x] button inside search view
int searchCloseButtonId = searchView.getContext().getResources()
.getIdentifier("android:id/search_close_btn", null, null);
ImageView closeButton = (ImageView) this.searchView.findViewById(searchCloseButtonId);
// Set on click listener
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Manage this event.
}
});
Inside onClick(View v) you can call a method to hide the keyboard like this
private void hideKeyboard(){
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
Hi all i am trying to put custom popup in layout popup is showing properly. If the button in pressed once and you click dismiss or outside area it is closing properly but when the button is pressed twice the popup is not all closing. Can anybody suggest on my below code.
popupView = getLayoutInflater().inflate(R.layout.word_meaning, null, false);
popupWindow = new PopupWindow(
popupView,
100,
100, true);
dismiss = (Button)popupView.findViewById(R.id.dismiss);
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
// Removes default black background
popupWindow.setBackgroundDrawable(new BitmapDrawable());
dismiss.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v) { System.out.println("dismiss");
// TODO Auto-generated method stub
popupView.setVisibility(View.GONE);
popupWindow.dismiss();
//System.out.println("View"+popupView.getVisibility());
}});
popupView.setVisibility(View.VISIBLE);
rel_layout.addView(popupView);
if you are trying to use the back button that is native to the device you want to put the closing action in a onBackPressed() method in the activity. ie
public void onBackPressed(){
//code
}
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 popup window displaying when I click an item in my list activity. The problem is that the back key doesn't close it. I tried catching the back key in my list activity but it doesn't register it...then I tried registering a onkeylistener to the view I'm passing to my popup window. Like this:
pop.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
boolean res=false;
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
// do something on back.
Log.e("keydown","back");
if (pw.isShowing()) {
Log.e("keydown","pw showing");
pw.dismiss();
res = true;
}
} else {
res = false;
}
return res;
}
});
which is passed to a popup like this:
pw = new PopupWindow(
pop,
240,
70,
true);
But that listener doesn't fire neither. Can you help me? I'm out of ideas :)
This is because the popup window does not respond to onTouch or onKey events unless it has a background that != null. Check out some code I wrote to help with this. In the basic case you can to call PopupWindow#setBackgroundDrawable(new BitmapDrawable()) to force it to act the way you expect. You won't need your own onKey listener. You might also need to call PopupWindow#setOutsideTouchable(true) if you want it to go away when the user clicks outside of the window boundaries.
Extended esoteric answer:
The reason the background cannot be null is because of what happens in PopupWindow#preparePopup. If it detects background != null it creates an instance of PopupViewContainer and calls setBackgroundDrawable on that and puts your content view in it. PopupViewContainer is basically a FrameLayout that listens for touch events and the KeyEvent.KEYCODE_BACK event to dismiss the window. If background == null, it doesn't do any of that and just uses your content view. You can, as an alternative to depending on PopupWindow to handle that, extend your root ViewGroup to behave the way you want.
Do as per following it works fine:
PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, true);
pw.setBackgroundDrawable(new BitmapDrawable());
pw.setOutsideTouchable(true);
pw.showAsDropDown(btnSelectWeight);
For new projects it's better to use
popupWindow.setBackgroundDrawable(new ColorDrawable());
instead of
popupWindow.setBackgroundDrawable(new BitmapDrawable());
as BitmapDrawable is deprecated. Also, it's better than ShapeDrawable in this case. I noticed that when PopupWindow is a rectangle with rounded corners, ShapeDrawable fills corners with black.
A really simple solution is to write pw.setFocusable(true), but probably you don't want to do this because then the MapActivity won't handle touch events.
A better solution is to override the back key, e.g like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Override back button
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (pw.isShowing()) {
pw.dismiss();
return false;
}
}
return super.onKeyDown(keyCode, event);
}
Good luck!
For the new searchers, as creating a new BitmapDrawable is not allowed now(The constructor BitmapDrawable() is deprecated) , so that you have to change it to a new ShapeDrawable(), so that you will change :
pw.setBackgroundDrawable(new BitmapDrawable());
To :
pw.setBackgroundDrawable(new ShapeDrawable());
And the whole work will be like :
PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, true);
pw.setOutsideTouchable(true);
pw.setBackgroundDrawable(new ShapeDrawable());
pw.setTouchInterceptor(new OnTouchListener() { // or whatever you want
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE) // here I want to close the pw when clicking outside it but at all this is just an example of how it works and you can implement the onTouch() or the onKey() you want
{
pw.dismiss();
return true;
}
return false;
}
});
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
just use this
mPopupWindow.setBackgroundDrawable(new BitmapDrawable(null,""));
which is not deprecated. i'd avoid new ShapeDrawable() as its going to render slowly as it tries to draw a shape when the screen needs to be redrawn.
I hope this will be help for you
pw.setTouchInterceptor(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pw.dismiss();
}
return true;
}
});
you need add setBackgroundDrawable(new BitmapDrawable()) for your PopupWindow.
private void initPopupWindow() {
// TODO Auto-generated method stub
View view = getLayoutInflater().inflate(R.layout.main_choice, null);
ListView main_menu_listview = (ListView) view.findViewById(R.id.main_menu_listview);
ShowMainChoice madapter = new ShowMainChoice(context);
main_menu_listview.setAdapter(madapter);
int width = (int)getWindowManager().getDefaultDisplay().getWidth()/2;
popupWindow = new PopupWindow(view, width,WindowManager.LayoutParams.WRAP_CONTENT);
popupWindow.setBackgroundDrawable(new BitmapDrawable());//this is important,如果缺少这句将导致其他任何控件及监听都得不到响应
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
main_menu_listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
// TODO Auto-generated method stub
Log.e("++++++>", arg2+"");
}
});
}
This problem is popupwindow底层的消息机制决定的,因为它是阻塞式的。Good luck
pw.setBackgroundDrawable(new ColorDrawable());
must wrote it before setContentView
This works for me.
Are you looking for the combination of the popupwindow dismiss and a good working of the BACK button, then you may consider the below solution.
Solution principle: all button clicks near your popup window will be intercepted, but any BACK button will not be intercepted. So, if you have anything in you popupwindow that takes action, then set an indication just before your call to dismiss(). In your setOnDismissListener() perform an extra action (like getActivity().popupBackStack()).
The advantage of this solution is that you can create your own CustomPopupWindow and implement this strategy. You can hide this implementation in your custom popup window.
Step 1: add near to your instantiation of your Popup Window:
boolean isClickHandled = false;
popupWindow.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(new ShapeDrawable());
popupWindow.setTouchInterceptor(new View.OnTouchListener() { // or whatever you want
#Override
public boolean onTouch(View v, MotionEvent event) {
isClickHandled = true;
return false;
}
});
If you have buttons inside your popupWindow, have the setOnClickListener.onClick set the isClickHandled = true and dismiss().
In your onDismissListener do something like:
popupWindow.setOnDismissListener(() -> {
popupWindow.dismiss();
if ( !isClickHandled) {
MainActivity.mainActivity.getSupportFragmentManager().popBackStack();
}
});