Good day.
I have an android application and I have a custom listView. Upon clicking the customListView I change the layout of the selected row (I change the last 2 column to editTexts), and I show a dialogFragment (which has an editText). Here is my code:
The onItemClickListener:
resultListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) {
//first I move the selected row to the top of the listView
resultListView.smoothScrollToPositionFromTop(pos, 0);
//then I disable selection of the listView to limit user action
resultListView.setScrollContainer(false);
resultListView.setClickable(false);
resultListView.setEnabled(false);
//I try to make the row still enabled and clickable
view.setClickable(true);
view.setEnabled(true);
//TODO - set clickstate = 0 is base/default state
for(SearchResultListViewItem row : results){
row.setClickState(1); //state 1 = dim
}
SearchResultListViewItem rowItem = results.get(pos);
rowItem.setClickState(2); //state 2 - clicked state
//in my CustomAdapter, I handle the clickState in the getView method
//basically, the change happens when click state is 2, the last 2 columns become editText
adapter.updateResults(results);
//I removed a lot of unrelated code in here
ItemDialog itemDialog = new ItemDialog();
//I set various variables here
itemDialog.show(getFragmentManager(), "");
};
});
This is the onCreateDialog Method. As you can see below, I set various properties such as setCancelable, setCancelOnTouchOutside, and window Flags for Modal.
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = new Dialog(getActivity());
//set width height here
int width = getResources().getDisplayMetrics().widthPixels * 4/5;
int height = getResources().getDisplayMetrics().heightPixels;
dialog.getWindow().setLayout(width, height);
//set other features here
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//make sure that the dialog persists through certain events
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
LayoutInflater layoutInflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout2 = layoutInflater.inflate(R.layout.fragment_item_dialog, null);
dialog.setContentView(layout2);
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyDialog);
//set window properties such as modal, dim, and position
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.setGravity(Gravity.TOP|Gravity.LEFT);
WindowManager.LayoutParams params = window.getAttributes();
params.x = 50;
params.y = y;
params.copyFrom(window.getAttributes());
window.setAttributes(params);
//edited out a lot of extra code
dialog.show();
return dialog;
}
And if necessary, here is the code in the getView method in my Custom BaseAdapter that handles when I change the clickState to 2:
//the if condition checks if the clickstate is < 2, if < 2, do the default and dim state
//click state of 2 means that I use the other row layout which has 2 editTexts
else{
convertView = layoutInflater.inflate(R.layout.search_result_inflate, null);
holder = new ViewHolder();
holder.itemView = (TextView) convertView.findViewById(R.id.dialogItemName);
holder.itemView.setText(listData.get(position).getItemName());
holder.itemView.setBackgroundColor(Color.parseColor("#66B2FF"));
holder.priceView = (TextView) convertView.findViewById(R.id.price);
holder.priceView.setText(listData.get(position).getPrice());
holder.priceView.setBackgroundColor(Color.parseColor("#66B2FF"));
holder.discountView = (TextView) convertView.findViewById(R.id.discount);
holder.discountView.setText(listData.get(position).getDiscount());
holder.discountView.setBackgroundColor(Color.parseColor("#66B2FF"));
holder.qtyIn = (EditText) convertView.findViewById(R.id.qtyInput);
holder.qtyIn.setText(listData.get(position).getQtyInput());
holder.qtyIn.setFocusable(true);
holder.qtyIn.setClickable(true);
holder.discIn = (EditText) convertView.findViewById(R.id.discInput);
holder.discIn.setText(listData.get(position).getDiscInput());
holder.discIn.setFocusable(true);
holder.discIn.setClickable(true);
return convertView;
}
As you can see, I tried to enable the necessary rows as much as possible. However, it seems that the DialogFragment is blocking it.
I also tried to comment out the
resultListView.setScrollContainer(false);
resultListView.setClickable(false);
resultListView.setEnabled(false);
block of code in my OnItemClickListener but to no avail.
The funny/interesting thing about this is that I am able to select the editTexts in the new row, I can see the focus shift, however, the soft keyboard does not appear at all. The soft keyboard only appears when I click the editText inside the DialogFragment. Even switching focus from the EditText in the dialog Fragment to the one in the list view doesn't enable me to put input inside the EditText in the rows.
If it's conflict between the EditText in the background/base activity (the one in the rows) and the EditText in the DialogFragment, then I hope there's a way to properly switch focus as I cannot resort to removing either of them.
Does anyone have an idea on how to work around this? Any help is very much appreciated, thank you.
Edit: I removed the EditText in the DialogFragment and it still doesn't work.
Related
I have an activity that is basically a long form of entry fields.
On each row, I want to show a TextView to serve as hint text just below each EditText and I want the TextView to remain visible at all times when the user is entering data. Unfortunately, the soft keyboard obscures the hint text and always positions itself immediately below the EditText. Is there any technique that will allow the TextView below the EditText to also be visible when the soft keyboard appears and the contents are adjusted (via windowSoftInputMode=adjustResize|adjustPan), without having the user scroll ?
Vishavjeet got me on the right track in suggesting I scrolldown to reveal the view that may be overlapped by the keyboard. Below is a function similar to what I used to solve the problem. It can be called when the EditText above the TextView receives focus:
// View targetView; // View that may be hidden by keyboard
// ScrollView scrollContainerView; // Scrollview containing hiddenView
//
void assureViewVisible (View targetView, ScrollView, scrollContainerView) {
Window rootWindow = activity.getWindow();
Rect rMyView = new Rect();
View rootview = rootWindow.getDecorView();
rootview.getWindowVisibleDisplayFrame(rMyView); // Area not taken up by keyboard
int subTextPos[] = new int[2];
targetView.getLocationInWindow(subTextPos); // Get position of targetView
int subTextHt = targetView.getHeight(); // Get bottom of target view
if ((subTextPos[1]+subTextHt) > rMyView.bottom) { // Is targetView at all obscured?
int scrollBy = (subTextPos[1]+subTextHt) - rMyView.bottom + 10; // add a small bottom margin
mMeasurementViewScrollView.smoothScrollBy(0, scrollBy); // Scroll to subtext
}
}
EDIT:
By understanding the problem more deeply, I think that you should add scroll programatically when user clicks on the Edittext. Here is the code to do that:
private final void focusOnView()
{
new Handler().post(new Runnable()
{
#Override
public void run()
{
your_scrollview.scrollTo(0, your_EditBox.getBottom());
}});
}
From my personal experience I think there is not such way to do that. The thing you can do is place the hint textview toRightOf the editext. Or Use modern Approach by using a Hint Placeholder on Edittext:
In XML, it's simply android:hint="someText"
Programatically you can use edittext.setHint(int);
pass R.string.somestring in above method.
I have extended EditTextPreference, but the Dialog Message won't display. This happens if I add the dialogMessage programatically or in the the preferences.xml.
Here is my onBindDialogView:
AutoCompleteTextView editText = mEditText;
editText.setText(getText());
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
((ViewGroup) oldParent).removeView(editText);
}
onAddEditTextToDialogView(view, editText);
}
Is the dialog message really absent? It's probably there but its text color might make it less (or not) visible. (Or try to dismiss software keyboard). Try experimenting with dialog messages having a number of "\n" characters and see if that affects dialog layout. If so, it means the dialog message is actually there but camouflaged too well.
EditTextPreference brings a text view (in the preference_dialog_edittext.xml) that replaces the existing one (in the alert_dialog.xml) for the dialog message, but unfortunately with different text style, which might cause a visibility problem under certain themes. Even their sizes are different.
One solution might be to obtain the text color and size from the original text view to be replaced and apply them to the new one, but I would suggest retaining the original text view instead, because it's more likely to be visually consistent if there are any future UI changes. Try adding the following overrides
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setMessage(getDialogMessage()); // bring back the original text view
}
protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
int id = getContext().getResources().getIdentifier("edittext_container", "id", "android");
ViewGroup container = (ViewGroup) dialogView.findViewById(id);
container.removeAllViews(); // remove the new text view
super.onAddEditTextToDialogView(dialogView, editText);
}
If you think the dialog message and the edittext view is too far apart, they can be brought together a little closer by adding another override:
protected void showDialog(Bundle state) {
super.showDialog(state);
int id = getContext().getResources().getIdentifier("message", "id", "android");
TextView message = (TextView) getDialog().findViewById(id);
message.setPadding(message.getPaddingLeft(), message.getPaddingTop(), message.getPaddingRight(), 0);
}
and add the following line in the onAddEditTextToDialogView method after calling removeAllViews:
container.setPadding(container.getPaddingLeft(), 0, container.getPaddingRight(), container.getPaddingBottom());
Good day, apologies for the confusing title.
I am creating an android application and I need a dialog/pop up to appear at a specific X Y Position. I already have a working DialogFragmet as shown below:
public class ItemDialog extends DialogFragment implements OnClickListener{
//a lot of public and private variables here
public interface onSubmitListener {
void setOnSubmitListener(String qty, String disc, String instructions, UOMClass uom);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = new Dialog(getActivity());
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
LayoutInflater layoutInflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout2 = layoutInflater.inflate(R.layout.fragment_item_dialog, null);
dialog.setContentView(layout2);
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyDialog);
//snip snip more code
dialog.show();
//buttons - I set the buttons here
//editTexts - I set the edit texts here
//TextViews - I set the text views here
return dialog;
}
//more functions here
}
And I call it from my base activity as follows:
ItemDialog itemDialog = new ItemDialog();
//pass values from base activity to the ItemDialog here
itemDialog.show(getFragmentManager(), "");
However, I need to be able to see the base activity and input values in the edit texts in it. As of now, my DialogFragment covers a huge part of the screen and I'm unable to see the activity behind it. Clicking outside the Dialog Fragment cancels it as well.
I've searched on how to make an alert dialog float but to no avail.
Is there a way to display a Dialog Fragment over a certain area of the screen to allow the user to see and still input values in the base activity?
Any help is very much appreciated, thank you.
you can get window object and set it's layout parameters below code might help you.
Window window = getDialog().getWindow();
// set "origin" to top left corner, so to speak
window.setGravity(Gravity.TOP|Gravity.LEFT);
// after that, setting values for x and y works "naturally"
WindowManager.LayoutParams params = window.getAttributes();
params.x = 300;
params.y = 100;
window.setAttributes(params);
for more info Position of DialogFragment in Android
you can also set background color or bitmap to dialog
I have a popup menu implemented , which shows up on click of a button. This is my onclick method.
public void showOverflow(View view) {
boolean click = true;
Button action = (Button) findViewById(R.id.btbAction);
LayoutInflater inflater = (LayoutInflater) main.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.overflow_layout, null);
final PopupWindow pw = new PopupWindow(popupView,
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
pw.setOutsideTouchable(true);
if (click) {
pw.showAsDropDown(action, 0, 0);
click = false;
} else {
pw.dismiss();
click = true;
}
}
The popup window shows up when the button is clicked. Now, the problem is that the window is not dismissed when i touch outside the popup window.
I tried setting this property to the popup window
pw.setOutsideTouchable(true);
Things remain the same. Please help me fix this
You should change the setOutsideTouchable call's parameter to true:
pw.setOutsideTouchable(false);
Controls whether the pop-up will be informed of touch events outside
of its window. This only makes sense for pop-ups that are touchable
but not focusable, which means touches outside of the window will be
delivered to the window behind. The default is false.
If the popup is showing, calling this method will take effect only the
next time the popup is shown or through a manual call to one of the
update() methods.
Parameters: touchable true if the popup should receive outside touch
events, false otherwise
On the other hand, what is the click local variable supposed to do? It is set to true, so it will always force the pw to pop up, whenever the showOverflow method is called, and for no reason it is set to false later, because it's life cycle ends as you leave that method.
Your code should look something like this:
private LayoutInflater inflater;
private Button action;
private PopupWindow pw;
private View popupView;
/*
* (non-Javadoc)
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
popupView = inflater.inflate(R.layout.overflow_layout, null, false);
action = (Button) findViewById(R.id.action);
action.setOnClickListener(this);
}
public void showOverflow()
{
pw = new PopupWindow(getApplicationContext());
pw.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
pw.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
pw.setOutsideTouchable(true);
pw.setContentView(popupView);
pw.showAsDropDown(action, 0, 0);
}
The getApplicationContext() shoud be used in case you are inside an Activity class. Otherwise you should get the Context as a parameter.
change pw.setOutsideTouchable(true); to pw.setOutsideTouchable(false);
I know this is an old question but this is what I have done to fix it
The problem is:
You are creating a new instance of popupwindow everytime you call showOverFlow() thats why after you close the popupwindow another popup window will show
What will you do is initialize popupview in OnCreate
Then call popupwindow.showAsDropDown(view) in showOverFlow() method
And lastly you can check whether is it showing below code
Put this code in your button onclick
if(popupwindow.isShowing()){
popup.dismiss() }
else{
ShowOverflow()}
I am creating an application which using custom view and i have designed the layout using a class that extends view.
Now i have a help icon on that view which have to popup on click.I have tried dialog window but i need a window without title and border.
I have checked some games and they are using what exactly i need. Anybody can suggest a better solution?
here is my sample code to get help button
public boolean onTouchEvent(MotionEvent me) {
int action = me.getAction();
if(action == MotionEvent.ACTION_DOWN ){
x = me.getX();
y = me.getY();
if (x >= helpButtonX && x < (helpButtonX +help.getWidth())&&
y >= helpButtonY && y < helpButtonY + help.getHeight() )
{
// code toshow popup
}
}
}
Yes you can create a custom dialog with the layout designed by you.
For that simply create a dialog and set the layout by using setContentView() method.
For example:
Dialog dialog = new Dialog(myActivity.this);
dialog.setContentView(R.layout.myDialogLayout);
dialog.setTitle("");
dialog.setCancelable(true);
dialog.show();
You can create a hidden View that is set using relativeLayout over the other elements in the layout.xml. when the user clicks the help button, the visibility is changed to visible and the View is shown. YOu can then set an onclick listener on the View that when they touch it, it will be hidden again.
You can just use a PopupWindow with custom layout.
Add this code in your {//Code to show popup}
//Get a layout inflator
LayoutInflater li = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
//Initialize a popup window with custom xml view - R.layout.popup.xml
View popupView = li.inflate(R.layout.popup, null);
final PopupWindow pW = new PopupWindow(popupView,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
To dismiss it use pW.dismiss() wherever you want
Try this: http://android-er.blogspot.jp/2012/03/example-of-using-popupwindow.html