Some methods in another thread cannot be executed in Android - java

Problem
After clicking logout button, some actions sometimes are not executed. In the code below, sometimes the hideTabBar() and showAuth() seem not to be executed, but sometimes they are executed. Why?
Source Code
MainActivity.java
public void selectLogout(View view) {
AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(this);
mAlertDialogBuilder.setTitle("Logout").setMessage("Are you sure you wanna logout?");
mAlertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
mAlertDialogBuilder.setPositiveButton("Logout", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mWebview.postDelayed(new Runnable() {
#Override
public void run() {
mWebview.loadUrl(WEB_BASE + LOGOUT_TAG);
btnSlide.performClick();
hideTabBar();
showAuth();
}
}, 500);
}
});
mAlertDialogBuilder.show();
}
activity_main.xml
The android:onClick="selectLogout" is used to bind the onClick callback function to the logout button.
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="100dp"
android:background="#color/button_state_resource"
android:clickable="true"
android:onClick="selectLogout" >
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:src="#drawable/icon_logout" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="120dp"
android:text="Logout" />
</RelativeLayout>

Remember, any UI related changes MUST happen on the UI thread. Thus, if you try to change the UI in a background thread, it might throw errors. To solve this, you can use a Handler that can post jobs to the UI thread to run in sequence.
example:
private Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
//....some stuff
//initialize Handler
handler = new Handler();
}
public void selectLogout(View view) {
AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(this);
mAlertDialogBuilder.setTitle("Logout").setMessage("Are you sure you wanna logout?");
mAlertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
mAlertDialogBuilder.setPositiveButton("Logout", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mWebview.postDelayed(new Runnable() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
// update UI
mWebview.loadUrl(WEB_BASE + LOGOUT_TAG);
btnSlide.performClick();
hideTabBar();
showAuth();
}
});
}
}, 500);
}
});
mAlertDialogBuilder.show();
}

Related

Seekbar is null, even though it exists

My goal is to access a seekbar. I tried many things, even pulling the Seekbar seekingbar before the override, but I get always the null toast. R.layout.firstLayout, R.layout.secondLayout, R.id.seekingbar, they all exist.
This is my abbreviated code
public class MainActivity extends AppCompatActivity {
SeekBar seekingbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekingbar = (SeekBar) findViewById(R.id.seekingbar);
LayoutInflater inflater = getLayoutInflater();
final View firstLayout = inflater.inflate(R.layout.firstLayout, null);
final View secondLayout = inflater.inflate(R.layout.secondLayout, null);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
.setPositiveButton("Forward", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
AlertDialog dialog2 = new AlertDialog.Builder(MainActivity.this)
.setView(secondLayout)
.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (seekingbar == null)
{
Toast.makeText(MainActivity.this,"Null",Toast.LENGTH_LONG).show();
}
}
}).create();
dialog2.show();
}
}).create();
dialog.show();
}
});
}
}
firstLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/seekbarll"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
tools:context=".MainActivity">
<SeekBar
android:id="#+id/seekingbar"
style="#style/Widget.AppCompat.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:min="0"
android:progress="3" />
</LinearLayout>
Try to find the seekBar in the firstLayout after declaring it:
"firstLayout.findViewById(R.id.seekbar)"

AlertDialog Builder OnItemSelectedListener

I have a tyny, but annoying problem with the AlertDialog Builder.
I want to handle an item select in a custom made AlertDialog, but OnItemSelectedListener doesn't seem to pick my clicks.
Custom Dialog:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="60dp"
android:background="#AAFFFFFF"
android:orientation="vertical">
<TextView
android:text="English"
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="#+id/lang_english"
android:gravity="center_vertical"
android:background="#color/borders"
android:paddingLeft="10dp"
android:onClick="onLanguageButtonClicked" />
<View
android:layout_height="1dp"
android:layout_width="match_parent"
android:background="#000000" />
<TextView
android:text="عربى"
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="#+id/lang_arabic"
android:gravity="center_vertical"
android:background="#color/borders"
android:paddingRight="10dp"
android:onClick="onLanguageButtonClicked" />
<View
android:layout_height="1dp"
android:layout_width="match_parent"
android:background="#2e2e2e"/>
<TextView
android:text="کوردی "
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="#+id/lang_kurdish"
android:gravity="center_vertical"
android:background="#color/borders"
android:paddingRight="10dp"
android:onClick="onLanguageButtonClicked" />
</LinearLayout>
On button click I open the dialog and handle it:
public void onClickDrawer(View view) {
switch (view.getId()) {
case R.id.button_account_language:
handleLanguageDialog();
break;
case R.id.button_account_currency:
handleCurrencyDialog();
break;
default:
break;
}
}
And the handler:
private void handleLanguageDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.dialog_language);
builder.setOnItemSelectedListener(new AdapterView.
OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
SharedPreferences preferences = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
Log.i("info", "pressed" + Integer.toString(position));
restartInLocale(new Locale(preferences.getString("locale","")));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
builder.setNegativeButton("CANCEL", new DialogInterface
.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.create().show();
}
Is this the correct approach or am I missing something?
Thank you in advance!
I don't this is correct Approach, you are making it very much complex. If I am not wrong then you are trying to show Language selection dialog for that you should follow the below given steps.
Create string-array inside strings.xml resource file
<string-array name="lang">
<item>English</item>
<item>عربى</item>
</string-array>
When you want to show alert dialog write down below code
private void handleLanguageDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pick_color)
.setItems(R.array.lang, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
switch(which)
{
case 0:// English
break;
case 1:// عربى
break;
}
}
});
return builder.create();
}
This is the simplest way to show list of languages in alert dialog and without any positive or negative button .
It looks a bit off. It should look like this:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
// Add action buttons
.setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// sign in the user ...
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LoginDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
https://developer.android.com/guide/topics/ui/dialogs.html
private void handleLanguageDialog() {
ArrayList<String> listItems = new ArrayList<>();
listItems.add("English");
listItems.add("Arabic");
new AlertDialog.Builder(this)
.setTitle("title")
.setCancelable(false)
.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
}
}).setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// sign in the user ...
}
}).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).show();
}
Try to use setOnItemClick listener on the list/spinner view whichever you are using to display the list instead of builder itself. Like if you are using spinner to show the list use-
final Spinner spinner = (Spinner) layout.findViewById(R.id.spinner); spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3){
int item = spinner.getSelectedItemPosition();
commandWriter(item);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Try this: add click listener to the language item in your Dialog
onItemSelected() is applied for listview or spinner items your Dialog layout dialog_language does not have those.
Try this code:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Get the layout inflater
LayoutInflater inflater =getLayoutInflater();
View myview = inflater.inflate(R.layout.dialog_language, null);
// Inflate and set the layout for the dialog
builder.setView(myview);
TextView english = (TextView) myview.findViewById (R.id.lang_english);
english.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//do some stuff
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Log.i("info", "pressed" + Integer.toString(position));
restartInLocale(new Locale(preferences.getString("locale","")));
}
});
TextView arabic = (TextView) myview.findViewById (R.id.lang_arabic);
arabic.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//do other stuff
}
});
// Add action buttons
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.show();

Alert Dialog - how to implement Cancel and Okay button

I have got this Alert Dialog which has these two buttons (Ok and Cancel). I want to know how I go about implementing it.
So When you click on the cancel button it should close the alert dialog and return back to the fragment I am currently on. And if I click on the Ok button it should replace the current alert dialog and place it with another one.
this is my code below for the confimration. java file;
public class confirmation extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inf = getActivity().getLayoutInflater();
final View theDIalog = inf.inflate(R.layout.example_xml, null);
builder.setView(theDIalog);
AlertDialog dialog = builder.create();
theDIalog.findViewById(R.id.makeaTransferOk).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Okay button is clicked", Toast.LENGTH_SHORT).show();
}
});
theDIalog.findViewById(R.id.makeaTransferCancel).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
return dialog;
}
}
this is my code for the example_xml;
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffc0c0c0">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:id="#+id/makeaTransferCancel"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK"
android:id="#+id/makeaTransferOk"/>
</RelativeLayout>
Please could someone help me
Try this code for the functionality you have mentioned above:
AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
builder1.setMessage("Write your message here.");
builder1.setCancelable(true);
builder1.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//put your code that needed to be executed when okay is clicked
dialog.cancel();
}
});
builder1.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage("your message ");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); //<-- change it with ur code
}
} );
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
} );
alertDialog.show();
builder.setPositiveButton(text, new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}).setNegativeButton(text, new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}).create();

When button is clicked the Alert Dialog does not appear

I have an Alert Dialog that has an EditText where you input text and then add it to a ListView. Then on each item there is a Button I want to make that Button make an AlertDialog. The code below does not work.
This is my code...
public class DeleteRenameList extends Activity {
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alert=new AlertDialog.Builder(DeleteRenameList.this);
alert.setMessage("What do you want to do?");
alert.setPositiveButton("Rename", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
alert.setNegativeButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alert.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog ale=alert.create();
ale.show();
}
});
}}
Please Help.
Try this:
Make your custom dialog and present it:
//Make your class named CUstomDialogClass
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.widget.Button;
public class CustomDialogClass extends Dialog{
public Activity c;
public Dialog d;
public Button yes, no;
public CustomDialogClass(Activity a) {
super(a);
// TODO Auto-generated constructor stub
this.c = a;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customdialog);
}
}
In your MainActivity, place this code in your onCreate() method:
Button button = (Button)findViewById(R.id.yourid);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final CustomDialogClass dialog = new CustomDialogClass(MainActivity.this);
dialog.setTitle("Your Title");
dialog.show();
final Timer time = new Timer();
time.schedule(new TimerTask() {
#Override
public void run() {
dialog.dismiss();
}
}, 5000);
}
});
Finally, there's the layout for custom dialog which you can modify. I just gave an example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Yout Title"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your Message"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
And then you can add your listeners to it.
Hope this helps..:)
Your new onClickListener should be new View.onClickListener.
You should have something like this to start with:
Button button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new View.onClickListener(){
#Override
public void onClick(View v){
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("Are you sure you want to exit?")
.setIcon(R.drawable.ic_launcher)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
finish();
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
}).create().show();
}
});

How to call main activity's function from custom ArrayAdapter?

I've looked at a lot of similar questions and can't seem to get anything to work. I have a main class with a function like this that edits shows a dialog box then edits a List when a button is pressed.
public class EditPlayers extends SherlockFragmentActivity {
listPlayerNames.setAdapter(new EditPlayerAdapter(ctx,
R.layout.score_row_edit_player, listScoreEdit));
public void deletePlayer(final int position) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
EditPlayers.this);
// Setting Dialog Title
alertDialog.setTitle("Delete Player");
// Setting Dialog Message
alertDialog.setMessage("Are you sure?");
// Setting Delete Button
alertDialog.setPositiveButton("Delete",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listScoreEdit.remove(position);
updateListView();
}
});
// Setting Cancel Button
alertDialog.setNeutralButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
}
How do I access that function from the getView() in the adapter? Here's the XML for the row
<TextView
android:id="#+id/nameEdit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:layout_weight="70"
android:text="Name"
android:textColor="#666666"
android:textSize="22sp"
android:textStyle="bold" >
</TextView>
<Button
android:id="#+id/deletePlayer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="30"
android:text="Delete"
android:focusable="false" />
Here's the getView()
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = (LinearLayout) inflater.inflate(resource, null);
Score score = getItem(position);
TextView txtName = (TextView) convertView.findViewById(R.id.nameEdit);
txtName.setText(score.getName());
Button b = (Button)convertView.findViewById(R.id.deletePlayer);
b.setTag(position);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//call function here
}
});
return convertView;
}
I'm totally lost at this point so any help would be appreciated. Thanks!
I would recommend providing an interface back to your activity that lets it know when that button is pressed. I would not recommend calling an activity's method from an ArrayAdapter. It is too tightly coupled.
Try something like this:
Your Activity
public class EditPlayers extends SherlockFragmentActivity implements EditPlayerAdapterCallback {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EditPlayerAdapter adapter = new EditPlayerAdapter(this,
R.layout.score_row_edit_player, listScoreEdit);
adapter.setCallback(this);
listPlayerNames.setAdapter(adapter);
}
private void deletePlayer(final int position) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
EditPlayers.this);
// Setting Dialog Title
alertDialog.setTitle("Delete Player");
// Setting Dialog Message
alertDialog.setMessage("Are you sure?");
// Setting Delete Button
alertDialog.setPositiveButton("Delete",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listScoreEdit.remove(position);
updateListView();
}
});
// Setting Cancel Button
alertDialog.setNeutralButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void deletePressed(int position) {
deletePlayer(position);
}
}
Adapter:
public class EditPlayerAdapter extends ArrayAdapter {
private EditPlayerAdapterCallback callback;
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = (LinearLayout) inflater.inflate(resource, null);
Score score = getItem(position);
TextView txtName = (TextView) convertView.findViewById(R.id.nameEdit);
txtName.setText(score.getName());
Button b = (Button)convertView.findViewById(R.id.deletePlayer);
b.setTag(position);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(callback != null) {
callback.deletePressed(position);
}
}
});
return convertView;
}
public void setCallback(EditPlayerAdapterCallback callback){
this.callback = callback;
}
public interface EditPlayerAdapterCallback {
public void deletePressed(int position);
}
}
Your EditPlayerAdapter gets a Context passed to it. Activity extends Context
If the Context passed is your EditPlayers and you store a class-scoped reference to that Context in your Adapter, you can then do:
((EditPlayers) yourContextVar).function();
Better yet, make an interface of some sort. It will help clarify and organise your code and it applies the same principle.

Categories