I've implemented a popup dialog with a EditText element inside. I can't get Softkeyboard shown on the screen and due to it unable to fill the EditText element. The problem is pretty well known, but still I can't get it working. I've tried different options for solving this issue - see onCreate method. Thanks.
public class MyPopup extends AbstractPlainPopup {
protected Context _context;
public CreatePlaylistPopup(Context context) {
super(context);
_context = context;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = getLayoutInflater();
View container = inflater.inflate(R.layout.popup_new_playlist, null);
final EditText titleInput = (EditText) container.findViewById(R.id.my_text_view);
titleInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
InputMethodManager mgr = (InputMethodManager) _context.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(titleInput, InputMethodManager.SHOW_IMPLICIT);
//getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
//MyPopup.this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
}
});
container.findViewById(R.id.cancelButton).setOnClickListener(
new onCancelClick());
container.findViewById(R.id.createButton).setOnClickListener(
new onCreateClick());
setContentView(container);
}
abstract public class AbstractPlainPopup extends AlertDialog implements Observable {
public final static int CANCEL = 0;
public final static int OK = 1;
protected int _state;
protected ArrayList<Observer> observers = new ArrayList<Observer>();
public AbstractPlainPopup(Context context){
super(context);
}
public AbstractPlainPopup(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
Dialog dialog = new Dialog(this, R.style.Theme_Dialog_Transparent);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.enter_details);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Use this in onCreate() and not within focus change listener
Related
How can I create a custom popup class that accepts a simple string message? Im new to Android and help with code will be appreciated.
When a button is pushed in the main layout, the popup must pop up on the screen.
Custom popup class
public class CustomPopup extends PopupWindow {
private String message;
private Double anchorX;
private Double anchorY;
PopupWindow popup;
public CustomPopup(String message) {
super();
this.message = message;
}
public void showPopup(Activity context) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
}
Main Class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText messageTxt = (EditText) findViewById(R.id.messageTxt);
Button generateBtn = (Button) findViewById(R.id.generateBtn);
String message = messageTxt.getText().toString();
final CustomPopup popup = new CustomPopup(message);
generateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
popup.showPopup();
}
});
}
}
You can change the following code any way you need. This is just an example of how you make and implement a custom DialogFragment.
He is the code I use. I find it quite flexible because you can create several similar dialogs for slightly different tasks. You will need to create a layout file - this gives you a great deal of flexibility on function and style.
My layout file is fragment_ok_cancel_dialog.
To satisfy your requirements just create your own layout file with all the elements in it you need (like your image).
In the Activity that calls the dialog you will need to implement the Listener.
implements OkCancelDialogFragment.OkCancelDialogListener
Another advantage is with my code you can change the title and the message to fit the needs of any Activity.
private void callMyDialog(){
//Customize the title and message as needed
String title = "This is my dialog title";
String mess = "This is my dialog message";
OkCancelDialogFragment dialog = OkCancelDialogFragment.newInstance(title, mess);
dialog.show(getFragmentManager(), "OkCancelDialogFragment2");
}
Now you need to implement the dialog callback in the Activity that calls the DialogFragment.
#Override
public void onFinishOkCancelDialog(boolean submit) {
if(submit){
// Do something positive
}
else{
// Do something negative
}
}
Now the code for the DialogFragment:
public class OkCancelDialogFragment extends DialogFragment {
private static final String ARG_TITLE = "title";
private static final String ARG_MESSAGE = "message";
Context context = null;
private String title;
private String message;
private boolean submitData = false;
private OkCancelDialogListener mListener;
public OkCancelDialogFragment() {
}
public static OkCancelDialogFragment newInstance(String title, String message) {
OkCancelDialogFragment fragment = new OkCancelDialogFragment();
Bundle args = new Bundle();
args.putString(ARG_TITLE, title);
args.putString(ARG_MESSAGE, message);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
title = getArguments().getString(ARG_TITLE);
message = getArguments().getString(ARG_MESSAGE);
}
}
#Override
public Dialog onCreateDialog(Bundle saveIntsanceState){
context = getActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View rootView = inflater.inflate(R.layout.fragment_ok_cancel_dialog, null, false);
final TextView titleView = (TextView)rootView.findViewById(R.id.tvTitle);
final TextView messView = (TextView)rootView.findViewById(R.id.tvMessage);
titleView.setText(title);
messView.setText(message);
builder.setView(rootView)
// .setTitle(title)
.setPositiveButton(R.string.ok_button_dialog_title, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
submitData = true;
if(mListener == null) mListener = (OkCancelDialogListener) context;
mListener.onFinishOkCancelDialog(submitData);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
submitData = false;
if(mListener == null) mListener = (OkCancelDialogListener) context;
mListener.onFinishOkCancelDialog(submitData);
}
});
return builder.create();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
if(mListener == null) mListener = (OkCancelDialogListener) context;
}
catch (Exception ex){
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OkCancelDialogListener {
void onFinishOkCancelDialog(boolean submit);
}
}
Please note that .setTitle(title) is valid for API 23 or higher (or maybe API 21 or higher?).
You can create your custom xml layout
and in the OnClickListener of the button you can put this :
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
alertLayout = inflater.inflate(R.layout.YOUR_CUSTOM_POPUP_LAYOUT, null);
final AlertDialog alert = new AlertDialog.Builder(this).create();
alert.setView(alertLayout);
TextView msg= alertLayout.findViewById(R.id.YOUR_TEXTVIEW_ID);
alert.show();
after that you can add another button in your popup and set a listener on it to dismiss the layout after the click.
My progress bar is just a spinner.
I am showing two options to user and when user clicks an option, I show a dialog, so that user reads and understands it.
This is what I want.
When they click positive, it should show the spinner and keep calling service on background.
When they click negative, it should make the option unchecked.
Here is the code.
This radioGroup.setOnClickListener goes into onCreateView method of a fragment.
public class Choose_CountryFragment extends Fragment {
private RadioGroup radioGroup;
private TextView textView;
private String countryChosen = null;
ConnectionStatus connectionStatus = new ConnectionStatus(getContext());
public Choose_CountryFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_choose__country, container, false);
radioGroup = (RadioGroup) rootView.findViewById(R.id.country_choice_radio);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch(checkedId){
case R.id.countryCanada:
// do operations specific to this selection
countryChosen = "Canada";
Intent explicitServiceIntent = new Intent(getActivity(), Service.class);
explicitServiceIntent.putExtra("country", "Canada");
getActivity().startService(explicitServiceIntent);
connectionStatus.showProgress();
break;
case R.id.countryUSA:
countryChosen = "USA";
Dialog dialog = onCreateDialog(savedInstanceState);
dialog.show();
connectionStatus.showProgress();
break;
}
}
});
public Dialog onCreateDialog(final Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
Toast.makeText(getContext(), "Click Got it", Toast.LENGTH_LONG).show();
builder.setMessage(R.string.SignUpWarningInfo)
.setPositiveButton(R.string.gotIt, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent explicitServiceIntentUSA = new Intent(getActivity(), Service.class);
explicitServiceIntentUSA.putExtra("country", countryChosen );
getActivity().startService(explicitServiceIntentUSA);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
return;
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
}
ConnectionStatus.java
public class ConnectionStatus {
private Context _context;
private ProgressDialog progressDialog = null;
public ConnectionStatus(Context context) {
this._context = context;
}
public void showProgress(){
progressDialog = new ProgressDialog(_context);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
}
}
Error happens when I click USA.
Error I get
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:154)
at android.app.AlertDialog.<init>(AlertDialog.java:109)
at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
at com.a2.a2.ConnectionStatus.showProgress(ConnectionStatus.java:66)
at com.a2.a2.signUp.Choose_CountryFragment$1.onCheckedChanged(Choose_CountryFragment.java:73)
Your Context returning null
Change code in Choose_CountryFragment
public class Choose_CountryFragment extends Fragment {
...
protected Context mContext;
private ConnectionStatus connectionStatus
...
public Choose_CountryFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_choose__country, container, false);
...
connectionStatus = new ConnectionStatus(mContext);// initialize ConnectionStatus here
...
}
}
Override onAttach Inside Choose_CountryFragment
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
In Fragment, you have to use:
ProgressDialog progressDialog = new ProgressDialog(getActivity);
From the documentation, the getActivity() method returns the Activity this Fragment is currently associated with it.
Edit:
In Activity class, you have to use like:
ProgressDialog progressDialog = new ProgressDialog(YourActivityClassName.this);
Can I implement a Cordova WebView in a CustomDialog in android?
I want to click a button and this show me a dialog with the webview. I tried in this way but didn't work.
button = (Button) findViewById(R.id.buttonShowCustomDialog);
// add button click listener
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("Title...");
cwv = (CordovaWebView) findViewById(R.id.webview);
Config.init(this);
cwv.loadUrl("file:///android_asset/www/index.html");
dialog.show();
}
});
UPDATE2:
In fact, the extended Dialog doesn't event need to implement CordovaInterface. It just needs to override setContentView, and that's enough.
public class CordovaDialog extends Dialog {
private Context currentContext;
public CordovaDialog(Context context) {
super(context);
this.currentContext = context;
}
// we have to override this because we need to disable attaching to root when inflating (wtf cordova ??)
#Override public void setContentView(int layoutResID) {
final LayoutInflater inflater = LayoutInflater.from(this.currentContext);
View v = inflater.inflate(layoutResID, null, false);
super.setContentView(v);
};
}
I have the same issue. I have also tried to create a class which extends Dialog and implements CordovaInterface, but didn't have any luck witjh that either. It seems every time I call setContentView, Cordova just can't find the Activity associated to the Dialog, and logcat shows a warning saying that my Activity doesn't implement CordovaInterface but it does.
UPDATE:
Ok, I figured it out. So here's how I dit it. It's long but it works.
First of all, let's assume that the parent Activity, the one which is creating the dialog, is already implementing CordovaInterface. Also, let's say that your CordovaWebview is inside a layout.
Make a new class (CordovaDialog for example) which extends Dialog and implements CordovaInterface.
Make a new constructor for the CordovaDialog class which passes the context and the interface so you can set the CordovaInterface from parent activity (which should also implement CordovaInterface).
Override setContentView in the CordovaDialog so that it inflates the view without attaching to root (last params set to false).
In your main activity, create the dialog, call Config.init(), and call loadUrl for CordovaWebview.
public class CordovaDialog extends Dialog implements CordovaInterface {
CordovaInterface parentCordovaInterface;
Context currentContext;
public CordovaDialog(Context context, CordovaInterface ci) {
super(context);
this.parentCordovaInterface = ci;
this.currentContext = context;
}
#Override public void setContentView(int layoutResID) {
final LayoutInflater inflater = LayoutInflater.from(this.currentContext);
View v = inflater.inflate(layoutResID, null, false);
super.setContentView(v);
};
#Override
public Activity getActivity() {
return this.parentCordovaInterface.getActivity();
}
#Override
public ExecutorService getThreadPool() {
return this.parentCordovaInterface.getThreadPool();
}
#Override
public Object onMessage(String arg0, Object arg1) {
return this.parentCordovaInterface.onMessage(arg0, arg1);
}
#Override
public void setActivityResultCallback(CordovaPlugin plugin) {
this.parentCordovaInterface.setActivityResultCallback(plugin);
}
#Override
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
this.parentCordovaInterface.startActivityForResult(command, intent, requestCode);
}
}
And then in your the activity which implements CordovaInterface:
final CordovaDialog dialog = new CordovaDialog(this, this);
dialog.setOwnerActivity(this);
dialog.setContentView(R.layout.dialog_with_cordovawebview);
CordovaWebView cwv = (CordovaWebView) dialog.findViewById(R.id.webViewDialog);
Config.init();
cwv.loadUrl("file:///android_asset/www/index.html");
dialog.show();
How to set null validation in edittextpreference dialog so that if it is null, the user should not be able to click ok and some message should be displayed in the dialog itself. I have been trying to find it for a long time but no success....
edttxtpref = (EditTextPreference) getPreferenceScreen().findPreference(
"edttxtkey");
edttxtpref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(
android.preference.Preference preference, Object newValue) {
if (newValue.toString().trim().equals("")) {
Toast.makeText(getActivity(), "Username can not be empty",
Toast.LENGTH_LONG).show();
return false;
}
return true;
}
});
This way the validation is done and if we want to display the message in dialog itself then a custom dialog has to be created as already told by Phil.
I think what you are looking for is this. You are using the predefined PreferenceDialog (with EditText) and want to check if the Text is null. According to my knowledge, the "text" in this case is the changedPreference, therefore you can go with this:
Simply use an onPreferenceChangedListener for that.
yourPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object changedValue) {
if(changedValue == null) {
// handle it being null
return false;
} else {
return true;
}
}
});
For more advanced requirements, I would recommend that you implement your own Dialog and inside it, do whatever you desire. You can make that happen by defining a Preference list entry in .xml and then spawn the Dialog upon clicking on it.
Preference yourCustomPref = (Preference) findPreference("yourPref");
yourCustomPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
// spawn your dialog here
return true;
}
});
This is how you could implement your custom EditText Dialog:
public Builder buildDialog(final Context c) {
AlertDialog.Builder builder = new AlertDialog.Builder(c);
builder.setTitle("EditText Dialog");
builder.setMessage("Enter text:");
LinearLayout llV = new LinearLayout(c);
llV.setOrientation(1); // 1 = vertical
final EditText patName = new EditText(c);
patName.setHint("Enter text...");
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 1f);
lp.bottomMargin = 20;
lp.rightMargin = 30;
lp.leftMargin = 15;
patName.setLayoutParams(lp);
llV.addView(patName);
builder.setView(llV);
builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if(patName.getText().toString().length() > 0) {
} else {
}
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
return builder;
}
And then call it like this:
buildDialog(yourcontext).show();
When edittext is null then ok button will be disabled and as soon as the text is entered it will be enabled::
public class CustomEditTextPreference extends EditTextPreference implements
OnClickListener {
public CustomEditTextPreference(Context ctx, AttributeSet attrs, int defStyle)
{
super(ctx, attrs, defStyle);
}
public CustomEditTextPreference(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
}
private class EditTextWatcher implements TextWatcher
{
#Override
public void onTextChanged(CharSequence s, int start, int before, int count){}
#Override
public void beforeTextChanged(CharSequence s, int start, int before, int count){}
#Override
public void afterTextChanged(Editable s)
{
onEditTextChanged();
}
}
EditTextWatcher m_watcher = new EditTextWatcher();
/**
* Return true in order to enable positive button or false to disable it.
*/
protected boolean onCheckValue(String value)
{
if (value.trim().equals(""))
{
return false;
}
return true;
}
protected void onEditTextChanged()
{
boolean enable = onCheckValue(getEditText().getText().toString());
Dialog dlg = getDialog();
if(dlg instanceof AlertDialog)
{
AlertDialog alertDlg = (AlertDialog)dlg;
Button btn = alertDlg.getButton(AlertDialog.BUTTON_POSITIVE);
btn.setEnabled(enable);
}
}
#Override
protected void showDialog(Bundle state)
{
super.showDialog(state);
getEditText().removeTextChangedListener(m_watcher);
getEditText().addTextChangedListener(m_watcher);
onEditTextChanged();
}
}
I am creating a home automation app that has allows plugin views. I have been able to create a class as a sample plugin in a separate project (apk):
public class MyTestClass_IRDroidUIPlugIn extends Button implements IRDroidInterface{
Context mContext;
public MyTestClass_IRDroidUIPlugIn(Context context) {
super(context);
mContext = context;
setText("I was loaded dynamically! (1)");
setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// how do I show the dialog from here?
Activity.showDialog(1);
}}
);
}
public Dialog buildConfigDialog(int ID){
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage("Click the Button...(1)")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}
I can load this class at run time and create an instance of it:
try {
final File filesDir = this.getFilesDir();
final File tmpDir = getDir("dex", 0);
final DexClassLoader classloader = new DexClassLoader( filesDir.getAbsolutePath()+"/testloadclass.apk",
tmpDir.getAbsolutePath(),
null, this.getClass().getClassLoader());
final Class<View> classToLoad =
(Class<View>) classloader.loadClass("com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn");
mybutton = (View) classToLoad.getDeclaredConstructor(Context.class).newInstance(this);
mybutton.setId(2);
main.addView((View)mybutton);
} catch (Exception e) {
e.printStackTrace();
}
setContentView(main);
}
protected Dialog onCreateDialog(int id) {
switch (id) {
case 1:
return ((IRDroidInterface) mybutton).buildConfigDialog(id);
}
return null;
}
I want the plugin to be able to show a configuration dialog. Is there a way I can pass the Activity object to this class so it can use .showDialog(ID). This would be ideal so that the dialog life cycle can be managed properly.
Thanks in advance.
Maybe I'm missing something, but why can't you do something like this?
public class MyTestClass_IRDroidUIPlugIn extends Button implements IRDroidInterface{
Activity mContext;
public MyTestClass_IRDroidUIPlugIn(Activity context) {
super(context);
mContext = context;
...
setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mContext.showDialog(1);
}}
);
.....
}
When you're creating this class, you're already passing Activity into this class - so just use it.