Context
I'm working with popupwindows to allow a user to quickly rename a cardview in an activity.
I do this by using a ViewSwitcher to swap the TextView (original name) for an EditText(new name).
Problem
When the EditText and PopUpWindow to confirm are present an the user presses "RECENT APPS", you cannot for some reason get back into the app. ie. when you click it, it won't respond.
Diagnosis
I think it's an issue with Window Focus. I've tried EditText.clearFocus() from ET and dismissing all PopUps onPause, no luck.
Is there a way to use onFocusChangeListener to remove this issue?
Code (I've tried to remove as much superfluous items as possible)
TheHubActivity.java
public class TheHubActivity extends AppCompatActivity implements RecyclerViewAdapter.onCardClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
// KEYBOARD
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//... Set up recycle view
rvContent = new ArrayList<>();
}
#Override
public void onCardLongClick(Flow longClickedFlow, int cardPosition, View cardViewClicked) {
showLongClickPopUpMenu(longClickedFlow,cardPosition, cardViewClicked);
}
private void showLongClickPopUpMenu(final Flow longClickedFlow, final int cardPosition, final View cardViewClicked) {
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.popup_window_longclick, null);
LinearLayout viewGroup = (LinearLayout) layout.findViewById(R.id.popup_longclick);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(layout, RecyclerView.LayoutParams.WRAP_CONTENT,
RecyclerView.LayoutParams.WRAP_CONTENT);
popup.setFocusable(true);
// Getting a reference to Close button, and close the popup when clicked.
ImageView delete = (ImageView) layout.findViewById(R.id.popup_delete_item);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*.... Delete current Flow from internal file and UI */
popup.dismiss();
}
});
ImageView edit = (ImageView) layout.findViewById(R.id.popup_edit_item);
edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popup.dismiss();
renameFlow(cardPosition, cardViewClicked);
}
});
// Displaying the popup at the specified location, + offsets.
popup.showAsDropDown(cardViewClicked, cardViewClicked.getMeasuredWidth(),popupDisplayHeight, Gravity.TOP);
longClickPopup = popup;
}
private void renameFlow(final int cardPosition, final View cardViewClicked) {
final ViewSwitcher switcher = (ViewSwitcher) cardViewClicked.findViewById(R.id.rename_switcher);
final EditText rename = (EditText) switcher.findViewById(R.id.item_flow_rename);
rename.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (rename.hasFocus()) {
showEditPopupWindow(rename, cardViewClicked, switcher, cardPosition);
} else {
imm.hideSoftInputFromWindow(rename.getWindowToken(), 0);
}
}
});
switcher.showNext();
rename.requestFocus();
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
/* Forces keyboard */
}
private void showEditPopupWindow(final EditText newName, View cardViewClicked, final ViewSwitcher switcher, final int cardPosition) {
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.popup_window_editing, null);
LinearLayout viewGroup = (LinearLayout) layout.findViewById(R.id.popup_editing);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(layout, RecyclerView.LayoutParams.WRAP_CONTENT,
RecyclerView.LayoutParams.WRAP_CONTENT);
popup.setFocusable(false); // So that user can edit text
// Getting a reference to Close button, and close the popup when clicked.
ImageView confirmEdit = (ImageView) layout.findViewById(R.id.popup_confirm_item_changes);
confirmEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* .. Changes name of cardview through edit text */
switcher.showNext();
popup.dismiss();
newName.clearFocus();
}
}
});
ImageView cancelEdit = (ImageView) layout.findViewById(R.id.popup_cancel_item_changes);
cancelEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switcher.showNext();
popup.dismiss();
}
});
popup.showAsDropDown(cardViewClicked, cardViewClicked.getMeasuredWidth(),popupDisplayHeight, Gravity.TOP);
editingPopup = popup;
}
#Override
protected void onPause() {
dismissPopups();
super.onPause();
}
private void dismissPopups() {
if (longClickPopup!=null && longClickPopup.isShowing()) {
longClickPopup.dismiss();
}
if (editingPopup!=null && editingPopup.isShowing()) {
editingPopup.dismiss();
}
}
}
For Visual People
I solved the issue... and it was surprisingly larger and completely unrelated to the Focus/PopUps (tunnel vision does that I guess).
In my Manifest I was using android:launchMode="singleTop" which was creating weird behaviour when TheHubActivity was sent to recent apps because this was my entrance activity. From the Developer Docs singleTop functions like so:
Similarly, a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created. In other circumstances — for example, if an existing instance of the "singleTop" activity is in the target task, but not at the top of the stack, or if it's at the top of a stack, but not in the target task — a new instance would be created and pushed on the stack.
<activity
android:name=".TheHubActivity"
android:label="#string/app_name"
~~~~~~android:launchMode="singleTop"~~~~~~~~
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Related
I have a UI requirement showing a blocking DialogFragment, which can not be dismissed by clicking on the background.
Also when the DialogFragment is showing, any view under it cannot be clicked.
Things are working well except on the Samsung S9 device.
On Samsung S9, which has an edge button, when clicking around the edge button's edge, the view under the DialogFragment got clicked and the event performed, which is not as expected.
Here is a sample code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyDialogFragment myDialogFragment = new MyDialogFragment();
myDialogFragment.show(getSupportFragmentManager(), MyDialogFragment.TAG);
}
});
findViewById(R.id.background).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("wrong", "clicked!!!!---------------");
Toast.makeText(MainActivity.this, "Click!", Toast.LENGTH_LONG).show();
}
});
}
}
The layout is quite simple, just a LinearLayout with a button inside it.
Clicking button will show the blocking dialog.
The LinearLayout id is background, which should not be clicked after the dialog has shown.
The dialog code:
public class MyDialogFragment extends DialogFragment {
public static final String TAG = "Dialog";
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCancelable(false);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_dialog_layout, container, false);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
#Override
public void onResume() {
Window window = getDialog().getWindow();
Point size = new Point();
Display display = window.getWindowManager().getDefaultDisplay();
display.getSize(size);
window.setLayout((int) (size.x * 0.8), WindowManager.LayoutParams.WRAP_CONTENT);
window.setGravity(Gravity.CENTER);
super.onResume();
}
}
But now when the dialog is showing, click the area on the edge button, the background click listener can be entered, I can get the log and toast.
How to prevent this?
In the event that is firing I'd do
Fragment currentFrag = getSupportFragmentManager().findFragmentByTag(MyDialogFragment_TAG);
if (!(currentFrag instanceof MyDialogFragment))
{
// your code for when you're dialog fragment is not visible
}
setcancelable(false); can be used to block clicking on background till task completes
Give the root node an id
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintlayoutRoot"
Add an empty OnClickListener
public View onCreateView(...) {
View view = _inflater.inflate(R.layout.fragment_xyz, _container, false);
view.findViewById(R.id.constraintlayoutRoot).setOnClickListener(view1 -> {
});
I use following code to show a small popup:
public static PopupWindow showImportMenu(Activity activity, View anchor, PopupWindowClickListener onClickListener)
{
LayoutInflater inflater = LayoutInflater.from(activity);
PopupImportBinding binding = DataBindingUtil.inflate(inflater, R.layout.popup_import, null, false);
if (!RootTools.isRootAvailable())
binding.llImportRootMethod.setVisibility(View.GONE);
PopupWindow popupWindow = new PopupWindow(activity, null, R.attr.popupMenuStyle);
popupWindow.setFocusable(true);
popupWindow.setContentView(binding.getRoot());
popupWindow.setOutsideTouchable(true);
PopupWindowCompat.showAsDropDown(popupWindow, anchor, 0, 0, Gravity.BOTTOM);
View.OnClickListener clickListener = new View.OnClickListener()
{
#Override
public void onClick(View view)
{
onClickListener.onClick(popupWindow, view);
}
};
binding.llImportDefault.setOnClickListener(clickListener);
binding.llImportRootMethod.setOnClickListener(clickListener);
binding.llImportHTCFromContacts.setOnClickListener(clickListener);
binding.llImportManual.setOnClickListener(clickListener);
return popupWindow;
}
This works on a lot of devices but on some rare devices it does not work, like:
Android 5.1.1 root slim rom
maybe others... until now, I don't know more about other devices
I got the feedback that no popup is shown. Does anyone know why this is not working on the above mentioned device? And what I can do to make it work on this device as well?
EDIT
It seems like it's not clear that what I want is following:
use showAsDropDown not showAtLocation or similar, I never saw this problem with showAtLocation yet
my solution is working on nearly all devices, it seems to be a phone/rom specific problem, maybe it's not even solvable as it COULD be a bug in the device as well => if someone knows of such a bug, telling me would be fine as well
I don't want to use a dialog (or anything else) instead, that's not answering my question. I currently use a BottomSheet which is fine for me, but still I would like to know if the problem can be solved and somehow handled
I got the same problem on a Nexus 7 (not 2012) running the 5.1.1. It is finally fixed by adding this line:
popupWindow.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
I was having the same problem: my PopupWindow was not showing on my 5.1.1 android device but it was on others. I realised that I had to specify the width and height in order to be shown on that version (which is still compatible with the rest of the versions as well).
Here is an example:
popUp.setWidth(MATCH_PARENT);
popUp.setHeight(WRAP_CONTENT);
In my case, popup window have no sizes on few devices.
Try that after setContentView
50000 - just a big size for measure.
popupWindow.getContentView().measure(50000, 50000);
popupWindow.setWidth(popupWindow.getContentView().getMeasuredWidth());
popupWindow.setHeight(popupWindow.getContentView().getMeasuredHeight());
You can use screen size instead 50000
Some ROMs restrict usage of popupview with their own permissions. So user have to explicitly turn on permission to show pop up views.
Even MIUI will restrict popupview to be displayed by default.
Please have a look whether there is any permission in that ROMs or devices.
Try QuickAction
Activity (ExampleActivity1.java) to show how to use QuickAction:
public class Example1Activity extends Activity {
private static final int ID_ADD = 1;
private static final int ID_ACCEPT = 2;
private static final int ID_UPLOAD = 3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.example1);
ActionItem addItem = new ActionItem(ID_ADD, "Add", getResources().getDrawable(R.drawable.ic_add));
ActionItem acceptItem = new ActionItem(ID_ACCEPT, "Accept", getResources().getDrawable(R.drawable.ic_accept));
ActionItem uploadItem = new ActionItem(ID_UPLOAD, "Upload", getResources().getDrawable(R.drawable.ic_up));
//use setSticky(true) to disable QuickAction dialog being dismissed after an item is clicked
uploadItem.setSticky(true);
final QuickAction mQuickAction = new QuickAction(this);
mQuickAction.addActionItem(addItem);
mQuickAction.addActionItem(acceptItem);
mQuickAction.addActionItem(uploadItem);
//setup the action item click listener
mQuickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
#Override
public void onItemClick(QuickAction quickAction, int pos, int actionId) {
ActionItem actionItem = quickAction.getActionItem(pos);
if (actionId == ID_ADD) {
Toast.makeText(getApplicationContext(), "Add item selected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), actionItem.getTitle() + " selected", Toast.LENGTH_SHORT).show();
}
}
});
mQuickAction.setOnDismissListener(new QuickAction.OnDismissListener() {
#Override
public void onDismiss() {
Toast.makeText(getApplicationContext(), "Ups..dismissed", Toast.LENGTH_SHORT).show();
}
});
Button btn1 = (Button) this.findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mQuickAction.show(v);
}
})
Button btn2 = (Button) this.findViewById(R.id.btn2);
btn2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mQuickAction.show(v);
mQuickAction.setAnimStyle(QuickAction.ANIM_GROW_FROM_CENTER);
}
});
}
}
Output:
(source: unitid.nl)
## Ok i implemented popupwindow for sorting in my tab fragment and i checked working fine once try this
I used in that custom layout for popup window
final PopupWindow popupWindow = new PopupWindow(getActivity());
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.popmenu1t1, null);
l8[![enter image description here][1]][1] = (LinearLayout) view.findViewById(R.id.atoz);
l8.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
date_sort="0";
discount_sort="";
price_sort="";
alpha_sort="";
popupWindow.dismiss();
}
});
int width = 900;
int height = 400;
try {
WindowManager wm = (WindowManager)view.getContext().getSystemService(Context.WINDOW_SERVICE);
width = wm.getDefaultDisplay().getWidth();
height = wm.getDefaultDisplay().getHeight();
} catch (Exception e) {
e.printStackTrace();
}
popupWindow.setWidth(width*3/6);
popupWindow.setFocusable(true);
popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
popupWindow.setContentView(view);
popupWindow.setBackgroundDrawable(null);
popupWindow.setOutsideTouchable(true);
popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
Find the below attached screen shot popupwindow in my app
I had created a custom popup dialog shows at bottom of screen
public class MoreOptionDialog {
private Dialog dialog;
private Context context;
private int size;
public MoreOptionDialog(Context context) {
this.context = context;
}
public void showMoreOptionDialog(List<String> listMoreOption) {
dialog = new Dialog(new ContextThemeWrapper(context, R.style.DialogSlideAnim));
dialog.getWindow().setWindowAnimations(R.style.DialogSlideAnim);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
View view = View.inflate(context, R.layout.dialog_more_option, null);
dialog.setContentView(view, new LinearLayout.LayoutParams(utility.getScreenWidth() - 100, size));
dialog.getWindow().setGravity(Gravity.BOTTOM);
ListView listView = (ListView) view.findViewById(R.id.lvMoreOption);
MoreOptionAdapter moreOptionAdapter = new MoreOptionAdapter(context, listMoreOption, Gravity.CENTER);
listView.setAdapter(moreOptionAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
dialog.dismiss();
}
});
dialog.show();
}
}
And style is here
<style name="DialogSlideAnim">
<item name="android:windowAnimationStyle">#style/DialogAnimation</item>
<item name="android:windowBackground">#color/color_white</item>
<item name="android:windowFrame">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
</style>
And this dialog working in all devices :)
I have a syntax errors with my code , in the "getView" I want to make a listener for the button "update" to move to another activity :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater l = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View rowView = l.inflate(R.layout.temp, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.textView1);
ImageView imageView = (ImageView) rowView.findViewById(R.id.imageView1);
Button update = (Button) rowView.findViewById(R.id.button1);
// update.setOnClickListener(new View.OnClickListener() {
//
// #Override
// public void onClick(View v) {
//
// Intent redirect = new Intent(getApplicationContext(),Update.class);
// startActivity(redirect);
//
// }
// });
textView.setText(sa.get(position));
return rowView;
}
I've tried to fix these errors about "Intent" but I failed :(
The method startActivity(Intent) is undefined for the type new View.OnClickListener()
The method getApplicationContext() is undefined for the type new View.OnClickListener()
and even whene I moved these statements from "onClick" method the problem didn't change !!
I imported "Intent" library , how to solve that ????
If your adapter is in a different file you will need activity context.
You need to pass the activity context from your activity class to your adapter constructor.
http://developer.android.com/reference/android/content/Context.html#startActivity(android.content.Intent)
startActivity is a method of your activity class. So you need activity context to start the activity.
Also instead of getApplicationContext use activity context.
When to call activity context OR application context?
Check the answer by commonsware.
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent redirect = new Intent(context,Update.class);
context.startActivity(redirect);
}
});
Try
final Activity thisActivity = this;
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent redirect = new Intent(thisActivity,Update.class);
thisActivity.startActivity(redirect);
}
});
for similar problem for me just this helped me :
#Override
public void onClick(View v) {
Intent intent = new Intent(G.context, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
G.context.startActivity(intent);
}
});
add context in G Class :
public class G extends Activity {
public static Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = getApplicationContext();
}
}
You just need to call context.startActivity instead, can follow below steps
Three simple steps
1) Declare local Variable Context mCtx
2) intialize it with Activity context either by passing a parameter to constructor/method, or in the onCreate method if you are using above code in activity.
3) call mCtx.startActivity(intent);
or
you can call ActivityName.this.startActivity()
Edit:- As par dmon comment, You simply can use your local context instance
The root of your problem is that you cannot start an Activity from an application Context (only from an activity context you have the right to do that). The reason for that is that android bundles all activities of your application as a group (task) in order to allow multitasking between different apps. When you launch a new app, or press the home button for example, you are application (together with its activities backstack) is going to the background and leaves the scene to a new task (with a different activity backstack and so on and so forth). For more info on this mechanism you can take a look here (http://developer.android.com/guide/components/tasks-and-back-stack.html).
In order to gain a context that is ok to lauch a new activity from, you can always get the context of the parent of the view you are inflating, by calling viewgroup.getContext() - eventhough you will have to declare the viewgroup as final, which is ok since you shouldn't be touching the parent.
a draft of your getView:
#Override
public View getView(int position, View convertView, final ViewGroup parent) {
LayoutInflater l = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View rowView = l.inflate(R.layout.temp, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.textView1);
ImageView imageView = (ImageView) rowView.findViewById(R.id.imageView1);
Button update = (Button) rowView.findViewById(R.id.button1);
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent redirect = new Intent(parent.getContext(),Update.class);
startActivity(redirect);
}
});
textView.setText(sa.get(position));
return rowView;
}
Sorry if the title was a bit vague.
I'm developing an app on Freelancer and I almost have it finished except for a complaint from the customer after some testing.
I use a PopupWindow in place of a dialog to edit contextual settings, if that makes any sense. I don't want to be too specific and risk giving the app concept away, which I'm sure the customer wouldn't be too pleased about.
The PopupWindow is given a Content View of a layout inflated from XML. In that layout are several EditText widgets. The issue is that those EditTexts will not trigger the default contextual dialog on long press that presents options for text/IME selection, and cut/copy/paste.
I saw a similar question trying to get the TouchTrigger or something and it not working without setBackgroundDrawable(), which I've tried with a simple new ColorDrawable(). It still doesn't work.
Is there any easy way to trigger the system-default long-press dialog in an OnLongPressListener, or will I have to move Heaven and Earth to implement it myself? Because if that's the case, I'll just write a Fragment for it and swap it out in a transaction. I know that'll work.
The relevant code:
Inside the initiating fragment:
RulesDialog dialog;
PopupWindow window;
public void showAddRuleDialog(){
dialog = new RulesDialog();
View view = getView();
window = new PopupWindow(dialog.initViews(this, null), view.getWidth(), view.getHeight(), true);
window.setBackgroundDrawable(new ColorDrawable());
dialog.setRulesDialogListener(new rulesDialogListener(){
#Override
public void onSave(ViewHolder holder) {
addRule(holder);
window.dismiss();
}
#Override
public void onCancel() {
window.dismiss();
}});
int[] location = {0,0};
view.getLocationOnScreen(location);
window.showAtLocation(view, 0, location[0], location[1]);
In RulesDialog:
public class ViewHolder{
public ViewHolder(View dialogView){
name = (TextView) dialogView.findViewById(R.id.name);
response = (TextView) dialogView.findViewById(R.id.response);
senders = (TextView) dialogView.findViewById(R.id.senders);
sendersAdd = (Button) dialogView.findViewById(R.id.sendersAdd);
sendersEdit = (Button) dialogView.findViewById(R.id.sendersEdit);
timeFrom = (TextView) dialogView.findViewById(R.id.from);
timeFromEdit = (Button) dialogView.findViewById(R.id.timeBeforeEdit);
timeTo = (TextView) dialogView.findViewById(R.id.to);
timeToEdit = (Button) dialogView.findViewById(R.id.timeAfterEdit);
keywords = (TextView) dialogView.findViewById(R.id.keywords);
matchCase = (CheckBox) dialogView.findViewById(R.id.matchCase);
matchAlone = (CheckBox) dialogView.findViewById(R.id.matchAlone);
matchPlural = (CheckBox) dialogView.findViewById(R.id.matchPlural);
cancel = (Button) dialogView.findViewById(R.id.cancel);
save = (Button) dialogView.findViewById(R.id.save);
}
TextView name;
TextView response;
TextView senders;
Button sendersAdd;
Button sendersEdit;
TextView timeFrom;
Button timeFromEdit;
TextView timeTo;
Button timeToEdit;
TextView keywords;
CheckBox matchCase;
CheckBox matchAlone;
CheckBox matchPlural;
Button cancel;
Button save;
}
Activity activity;
ViewHolder holder;
Fragment fragment;
public View initViews(Fragment mFragment, Rule rule){
fragment = mFragment;
activity = fragment.getActivity();
View dialogView = LayoutInflater.from(activity).inflate(R.layout.rules_dialog, null);
holder = new ViewHolder(dialogView);
final TextView senders = holder.senders;
holder.sendersAdd.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
showContacts();
}});
holder.sendersEdit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
editSenders(senders);
}
});
final TextView timeFrom = holder.timeFrom;
holder.timeFromEdit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
showTimePickerDialog(timeFrom);
}
});
final TextView timeTo = holder.timeTo;
holder.timeToEdit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
showTimePickerDialog(timeTo);
}
});
holder.cancel.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
mListener.onCancel();
}});
holder.save.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
mListener.onSave(holder);
}});
if(rule == null)
rule = new Rule();
holder.name.setText(rule.name);
holder.response.setText(rule.response);
holder.senders.setText(rule.senders.toString());
holder.senders.setTag(rule.senders);
holder.keywords.setText(rule.keywords);
holder.matchCase.setChecked(rule.matchCase);
holder.matchAlone.setChecked(rule.matchAlone);
holder.matchPlural.setChecked(rule.matchPlural);
holder.timeFrom.setTag(rule.timeFrom);
holder.timeFrom.setText(Rules.formatTime(rule.timeFrom));
holder.timeTo.setTag(rule.timeTo);
holder.timeTo.setText(Rules.formatTime(rule.timeTo));
return dialogView;
}
So I tried rewriting RulesDialog as a fragment, and it didn't work out too well. Had issues with making Fragment Transactions work right when called from the Fragments they're operating on.
(I know this isn't the point to fragments. I'm not really aiming to write a completely modular app right now. I just want to come out with a product the customer will be happy with.)
I ended up rewriting RulesDialog as an Activity instead, and using startActivityForResult() from the calling fragment. Then passing the edited data back with setResult(). It all works nicely in concert.
I'm having a very frustrating problem with PopupWindow on Android.
I've implemented my own class that inherits PopupWindow and implements
OnClickListener.
After adding button backgrounds with custom selectors problems start.
This background keeps disappearing after clicking the button (starting new activity and dismissing the popup).
It doesn't disappear after "focus and click", only after "quick click".
Any idea/suggestion would be very appriciated!
public class TestPopup extends PopupWindow implements OnClickListener
protected LayoutInflater inflater;
protected Activity caller;
protected View popup;
protected View layout;
public TestPopup(Activity activity) {
super(activity);
popup = inflater.inflate(R.layout.popup, (ViewGroup) caller.findViewById(R.id.contentLayout));
layout = popup.findViewById(R.id.layout);
popup.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
Display display = caller.getWindowManager().getDefaultDisplay();
setHeight(display.getHeight());
setWidth(display.getWidth());
setFocusable(true);
setContentView(popup);
// fix to allow Popup to be clickable!
setBackgroundDrawable(new BitmapDrawable());
popup.setOnClickListener(this);
popup.findViewById(R.id.addButton).setOnClickListener(this);
popup.findViewById(R.id.deleteButton).setOnClickListener(this);
}
public void onClick(View v) {
Intent intent = null;
if (v.getId() == R.id.addButton) {
intent = new Intent(caller, AddActivity.class);
intent.putExtra(AddActivity.ACTION_ADD, true);
} else if (v.getId() == R.id.deleteButton) {
intent = new Intent(caller, AddActivity.class);
intent.putExtra(AddActivity.ACTION_DELETE, true);
}
if (intent != null) {
caller.startActivity(intent);
}
TestPopup.this.dismiss();
}
One solution is to call popup.invalidate(); before dismissing the popup.