Android custom Progress Dialog - setCancelable() - java

I had created a custom Progress Dialogue. Overriding properties like setCancelable() , setCanceledOnTouchOutside() doesn't worked for me.
public class CustomProgressDialogue extends ProgressDialog {
private final Context context;
public CustomProgressDialogue(Context context) {
super(context);
this.context = context;
getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_view);
}
// Didn't worked
#Override
public void setCancelable(boolean flag) {
super.setCancelable(false);
}
// Didn't worked
#Override
public void setCanceledOnTouchOutside(boolean cancel) {
super.setCanceledOnTouchOutside(false);
}
}
But the same time applying same properties after the instance creation worked.
// Worked
progressDialogue = new CustomProgressDialogue(getContext());
progressDialogue.setCancelable(false);
progressDialogue.setCanceledOnTouchOutside(false);
Could you please somebody can explain this?

instead of overriding the cancel-able method create a static method like this and then pass it the required options
here's how ProgressDialog class do this:
public static ProgressDialog show(Context context, CharSequence title,
CharSequence message, boolean indeterminate,
boolean cancelable, OnCancelListener cancelListener) {
ProgressDialog dialog = new ProgressDialog(context);
dialog.setTitle(title);
dialog.setMessage(message);
dialog.setIndeterminate(indeterminate);
dialog.setCancelable(cancelable);
dialog.setOnCancelListener(cancelListener);
dialog.show();
return dialog;
}

You can try with this way
public class CustomProgressDialogue extends ProgressDialog
{
public static ProgressDialog(Context context) { // This section create Main role .
CustomProgressDialogue dialog = new CustomProgressDialogue (context);
dialog.setCancelable(false); // Add this
return dialog;
}
public CustomProgressDialogue (Context context) {
super(context);
}
public CustomProgressDialogue (Context context, int theme) {
super(context, theme);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_view);
}
#Override
public void show() {
super.show();
}
#Override
public void dismiss()
{
super.dismiss();
}
}

you cann add
public static ProgressDialog(Context context) {
CustomProgressDialogue dialog = new CustomProgressDialogue (context);
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
my method is
final AlertDialog alertD = new AlertDialog.Builder(context).create();
alertD.setCanceledOnTouchOutside(false);
is work...!

The issue with your code is that you are overriding the cancelable and OutsideTouchCancel in your CustomDialog class but you are not replacing the original code from ProgressDialog class. So when you call super(context) on your constructor it will initiate your dialog with its build in function for Cancelable and OutsideTouchCancel.
So in your constructor of CustomDialog you need to explicitly call
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false)
You are not required to override those function in your custom class.

Related

Constructor of worker it doen't called?

I try to implement a timer using Work Manager.
"Timer button was hit" is appear in logcat, but nothing comes from worker. What I do wrong?
This is my ViewModel class:
public class MainViewModel extends ViewModel {
public static final String LOG_TAG = "MainActivity";
private final WorkManager workManager;
public MainViewModel(WorkManager workManager) {
this.workManager = workManager;
}
public void count() {
Log.d(LOG_TAG, "Timer button was hit!");
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(MainWorker.class).build();
workManager.beginUniqueWork("count-work", ExistingWorkPolicy.APPEND, request).enqueue();
}
}
This is my worker. Nothing appear in logcat from here. I don't know why.
public class MainWorker extends Worker {
public MainWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
Log.d(MainViewModel.LOG_TAG, "Created");
}
#NonNull
#Override
public Result doWork() {
Log.d(MainViewModel.LOG_TAG, "Work start");
return Result.success();
}
}
This is my activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainViewModel viewModel = new MainViewModel(WorkManager.getInstance(this));
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setMainViewModel(viewModel);
}
}
ViewModels are not initialized the way you did. If you have to pass something to ViewModel constructor, you should probably consider using ViewModelProvider.Factory().
You can make your own ViewModelProvider.Factory()
Refer this, https://medium.com/koderlabs/viewmodel-with-viewmodelprovider-factory-the-creator-of-viewmodel-8fabfec1aa4f#:~:text=And%20it%20is%20because%20you,it%20will%20create%20your%20ViewModel.

change Main UI from custom Dialog Class

I have 2 class, Main and DialogOrder
Main
public class Main extends Fragment{
ImageView order;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
order.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new DialogOrder(getActivity()).show();
}
});
return view;
}
public void init(Bundle savedInstanceState) {
order = (ImageView) view.findViewById(R.id.order);
order.setImageResource(R.drawable.orderd);
RelativeLayout.LayoutParams orderparams = new RelativeLayout.LayoutParams(Main.screenHeight / 8, Main.screenHeight / 8);
orderparams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
orderparams.addRule(RelativeLayout.CENTER_HORIZONTAL);
orderparams.setMargins(Main.screenHeight / 80, Main.screenHeight / 80, Main.screenHeight / 80, Main.screenHeight / 30);
order.setLayoutParams(orderparams);
}
public void update_UI(){
order.setVisibility(View.INVISIBLE);
}
}
DialogOrder
public class DialogOrder extends Dialog {
Button button;
Main main;
Activity context;
public DialogOrder(Activity context) {
super(context);
this.context = context;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.order_dialog);
main = new Main();
button = (Button)findviewbyid(R.id.bd);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
main.update_UI();
dismiss();
}
});
}}
what I want is to set order image INVISIBLE when the user press the button on dialog
right now the code give me
java.lang.NullPointerException
probably I try update the UI wrong
so please can someone tell me what the right way to update parent UI class from child class ?
You can update your main fragment by passing it to Dialog constructor or you can use Listener/Callback to communicate between your main fragment and dialog.
The best practice is is using Listener/Callback because a Dialog should not have access to the caller. This is also decouple Dialog from Main fragment.
First, create the listener via interface in the dialog:
public class DialogOrder extends Dialog {
...
Activity context;
private DialogListener listener;
public interface DialogListener {
void onButtonClicked();
}
public DialogOrder(Activity context, DialogListener listener) {
super(context);
this.context = context;
this.listener = listener;
}
...
}
Then, when button click call the listener:
public class DialogOrder extends Dialog {
Activity context;
private DialogListener listener;
public interface DialogListener {
void onButtonClicked();
}
public DialogOrder(Activity context, DialogListener listener) {
super(context);
this.context = context;
this.listener = listener;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
...
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onButtonClicked();
dismiss();
}
});
}
}
Now, you can create the dialog with the listener. Something like this:
DialogOrder.DialogListener listener = new DialogOrder.DialogListener() {
#Ovveride
public void onButtonClicked() {
update_UI();
}
};
DialogOrder dialogOrder = new DialogOrder(getActivity(), listener);
dialogOder.show();
The main fragment will be listening for button clicked in the dialog.

android create ProgressDialog in constructor

I created Activity that includes ProgressDialog and its methods.
public class ProgressActivity extends AppCompatActivity implements Thread.UncaughtExceptionHandler {
public final ProgressDialog progressDialog;
public void dismissPD() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
public void setPDMessage(String msg) {
progressDialog.setMessage(msg);
}
public void showPD(String msg) {
ProgressDialog.show(this, "", msg);
}
#Override
public void uncaughtException(Thread thread, Throwable ex) {
ex.printStackTrace();
}
public ProgressActivity() {
progressDialog = new ProgressDialog(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
dismissPD();
}
}
Now I extend my new activity from it, but I get NullpointerException inside constructur on progressDialog = new ProgressDialog(this)
As I see, I have a wrong context when constructor runs. Is there a right approach to realize it in my way?
I solved the problem by overriding oncreate mothod of the main Activity:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressDialog = new ProgressDialog(this);
}

on click interface callback gives null in Android

I have Android module library which will create the Touch Keypad UI and set event listener for done and backbutton.
Also have main activity with implement eventCallback interface
MainActivity.java (Appication)
public class MainActivity extends AppCompatActivity implements eventCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v = new touchkey(this);
setContentView(v);
}
#Override
public void onClick() {
Log.i("test","complete");
Toast.makeText(this, "this is my Toast message!!! =)",
Toast.LENGTH_LONG).show();
}
}
eventCallback.java (Android Module Library)
public interface eventCallback {
void onClick();
}
touchkey.java (Android Module Library)
public class touchkey extends RelativeLayout{
private static touchkey INSTANCE;
TextView bclear;
ImageView bdone;
eventCallback eventCall;
public touchkey(Context context) {
super(context);
initialize(context);
}
public touchkey(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
public void test() {
Log.i("test","test");
}
private void initialize(Context context) {
inflate(context, R.layout.touchkey, this);
bclear = (TextView) findViewById(R.id.anti_theft_t9_key_clear);
bdone = (ImageView) findViewById(R.id.anti_theft_t9_key_done);
bdone.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (eventCall != null) {
eventCall.onClick();
}
}
});
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
but iam getting nullpointer exception on the touchkey.java
eventCall.onClick(); (eventCall is null)
I dont know where i am doing things wrong. can anybody help on this. Requirement: i need to handle the click event happening on the Library in Main Activity
You must create setter for eventCall (in touchkey.java):
public void setEventCall(eventCallback eventCall) {
this.eventCall = eventCall;
}
And, use it (in MainActivity):
View v = new touchkey(this);
setContentView(v);
((touchkey) v).setEventCall(this);

how to return result from asyn call

i have all my async calls in their own classes and so i dont want to have global vars being set aync'ly. To do this i want to return objects eg a string from my asunc postProcess methods.
can this be done?
Below is my general structure to my classes, i want to return a String for example from onPostExecute(). I see delegates are mentioned in other places but this seems very messy, sure there is a way to have a return type to the class or methods?
class GetStuffAsyncly extends AsyncTask<String, String, String>
{
// my vars....
public myconstructor(String dialogMessage, Context con)
{
this.qDialog = new ProgressDialog(con);
this.dialogString = dialogMessage;
this.context = con;
}
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute()
{
super.onPreExecute();
do stuff like fire dialog
}
#Override
protected String doInBackground(String... args)
{
// do stuff in background...
return data;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String jsonString)
{
// dismiss the dialog after getting all data
dialog.dismiss();
}
}
Some thing like below
class GetStuffAsyncly extends AsyncTask<String, String, String> {
String dialogString;
ProgressDialog dialog;
Context context;
AsyncListener listener;
// my vars....
public GetStuffAsyncly(String dialogMessage, Context con, AsyncListener listener) {
this.dialog = new ProgressDialog(con);
this.dialogString = dialogMessage;
this.context = con;
this.listener = listener;
}
/**
* Before starting background thread Show Progress Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
listener.onTaskStarted();
}
#Override
protected String doInBackground(String... args) {
// do stuff in background...
return data;
}
/**
* After completing background task Dismiss the progress dialog
**/
protected void onPostExecute(String jsonString) {
// dismiss the dialog after getting all data
dialog.dismiss();
listener.onTaskFinished(jsonString);
}
}
And the listener class
public interface AsyncListener {
void onTaskStarted();
void onTaskFinished(String data);
}
and you can call like this
new GetStuffAsyncly(message, this, new AsyncListener() {
#Override
public void onTaskStarted() {
//do your stuff
}
#Override
public void onTaskFinished(String data) {
//Do your stuff;
}
}).execute(parameter);
Another option is to use AsyncTaskLoader. You derive your class not from AsyncTask, but from AsyncTaskLoader. In your Activity you need to implement LoaderCallbacks interface. The args you want to use in Loader, you put in Bundle. All information you want to get from Loader will be passed in method onLoadFinished(). Here's an example
public class BaseInitLoader extends AsyncTaskLoader<Employee[]> {
Context mContext;
boolean firstrun;
public BaseInitLoader(Context context, Bundle args) {
super(context);
mContext = context;
firstrun = args.getBoolean("firstrun");
}
#Override
protected void onStartLoading() {
super.onStartLoading();
forceLoad();
}
#Override
public Employee[] loadInBackground() {
MainActivity activity =(MainActivity) mContext;
Cursor cursor = new DatabaseFiller(activity.getDb(), mContext, firstrun).fillTable();
ArrayList<Employee> list = new ArrayList<>();
QueryResultIterable<Employee> itr = null;
try {
itr = cupboard().withCursor(cursor).iterate(Employee.class);
for(Employee employee: itr){
list.add(employee);
}
} finally {
// close the cursor
if (itr != null) {
itr.close();
}
}
Employee[] employees = new Employee[list.size()];
employees = list.toArray(employees);
return employees;
}
}
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks, View.OnClickListener {
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
TextView priority, name, innerPhone, mobilePhone, position;
Button cityBtn;
CharSequence[] cities;
SQLiteDatabase db;
Context mContext;
private Cursor cursor;
private SQLiteDatabase database;
private ListView listView;
private TextView nameTxt;
private EmployeeAdapter adapter;
public static final String LOG_TAG = "Database";
SharedPreferences prefs;
private boolean firstrun;
private ViewPager viewPager;
private TabLayout tabLayout;
private final int INITIAL = 1;
private final int SORT_NAME = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
Bundle args = new Bundle();
prefs = getSharedPreferences("ua.lanet.PipBoy", MODE_PRIVATE);
if(prefs.getBoolean("firstrun", true)){
args.putBoolean("firstrun", true);
prefs.edit().putBoolean("firstrun", false).apply();
}
else{
args.putBoolean("firstrun", false);
}
getLoaderManager().initLoader(INITIAL, args, this);
PipBoyDataHelper helper = new PipBoyDataHelper(this);
db = helper.getWritableDatabase();
}
public SQLiteDatabase getDb() {
return db;
}
#Override
public Loader onCreateLoader(int id, Bundle args) {
return new BaseInitLoader(mContext, args);
}
#Override
public void onLoadFinished(Loader loader, Object data) {
//do something with the data. Cast Object to your return type of loader
}
#Override
public void onLoaderReset(Loader loader) {
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.text:
getLoaderManager().initLoader(SORT_NAME, null, this);
break;
}
}
private class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
}

Categories