This is my task: When a user is logged in, The TextView will be invisible in my Activity. I'm using : http://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/
And here is my code:
if (session.isLoggedIn())
{
sgnin.setVisibility(View.INVISIBLE); //sgnin is my TextView i need to Invisible it.
}
Actual and General statement in tutorial:
if (!session.isLoggedIn()) {
logoutUser();
}
But after doing this, method ; setVisibility doesnt work!
Any ideas?
You're probably not making that call on the UI thread. Try this instead:
runOnUiThread(new Runnable() {
#Override
public void run() {
sgnin.setVisibility(View.INVISIBLE)
}
});
Related
I have successfully implemented a custom Dialog box that appears when the user tries to leave an activity via a back button or by using onBackPressed(). They can simply cancel the dialog box or continue, and leave the activity. This function has been implemented in multiple activities, however its making my code a lot longer than it needs to be. I wanted to know how to create a util that can be referenced in different activities, without the need for the chunk of code to copy pasted multiple times. Please note that I am retrieving the dialog title and description from string.xml
This is my code:
Dialog customDialog;
Button button_one, button_two;
TextView dialog_title, dialog_description;
customDialog = new Dialog(this);
//Back button will close app
#Override
public void onBackPressed() {
customDialog.setContentView(R.layout.custom_dialog_box);
dialog_title = customDialog.findViewById(R.id.dialog_title);
dialog_title.setText(getString(R.string.leaving_activity_warning_title));
dialog_description = customDialog.findViewById(R.id.dialog_description); dialog_description.setText(getString(R.string.leaving_activity_warning_description));
button_one = customDialog.findViewById(R.id.button_one);
button_one.setText(getString(R.string.cancel));
button_two = customDialog.findViewById(R.id.button_two);
button_two.setText(getString(R.string.leave_anyway));
button_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
customDialog.dismiss();
}
});
button_two.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
customDialog.dismiss();
finish();
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
}
});
Objects.requireNonNull(customDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
customDialog.show();
}
UPDATE
Created a Java file called "DialogBoxMessage"
DialogBoxMessage Code:
class DialogBoxMessage {
private Dialog customDialog;
private TextView dialog_title, dialog_description;
private Button button_one, button_two;
//Custom Dialog Box Initialization
DialogBoxMessage(Button myButtonOne, TextView myDialogTitle, TextView myDialogDescription, Dialog myCustomDialog) {
customDialog = myCustomDialog;
button_one = myButtonOne;
button_two = myButtonOne;
dialog_title = myDialogTitle;
dialog_description = myDialogDescription;
}
void leaveActivity() {
customDialog.setContentView(R.layout.custom_dialog_box);
dialog_title = customDialog.findViewById(R.id.dialog_title);
dialog_title.setText(Resources.getSystem().getString(R.string.leaving_activity_warning_title));
dialog_description = customDialog.findViewById(R.id.dialog_description);
dialog_description.setText(Resources.getSystem().getString(R.string.leaving_activity_warning_description));
button_one = customDialog.findViewById(R.id.button_one);
button_one.setText(Resources.getSystem().getString(R.string.cancel));
button_two = customDialog.findViewById(R.id.button_two);
button_two.setText(Resources.getSystem().getString(R.string.leave_anyway));
button_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
customDialog.dismiss();
}
});
button_two.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
customDialog.dismiss();
}
});
Objects.requireNonNull(customDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
customDialog.show();
}
}
I input the following code in another activity
Other activity code:
//Reusable exit dialog message
DialogBoxMessage dialogBoxMessage;
//Back button will close app
#Override
public void onBackPressed() {
dialogBoxMessage.leaveActivity();
finish();
}
But it doesn't seem to work, I think there are a lot of issues... please help :(
I assume customDialog is a seperate class you wrote - therefore i would suggest you put main information like contentview, title, message or type in the constructor when you initialize ur Dialog.
For your onClick Method I suggest you create an Interface to handle Button Clicks in your
customDialog class.
This could be implemented as a static method in a utilities class. The method would require 'this' as a parameter, which contains the activity context. The method should return the result of the button press. The activity can use this response to determine if finish() should be called or not.
UPDATE
I had suggested a simple static method, but you've gone down the object-oriented route. That's fine.
However, your constructor requires passing in several views, which wouldn't appear to achieve the code efficiency you are after.
Your constructor should just require the Activity context; everything else is encapsulated in your new class.
In each Activity's onBackPressed method you will need to create the object with
dialogBoxMessage = new DialogBoxMessage(this);
before you can call any of that object's methods.
My app is working not correctly. Exactly when I click one button, I am logged out automatically. Here there is source code.
protected void previewStack() {
this.currentSubeditor.dataFromUIFields();
Toast.makeText(getApplicationContext(), "Generating preview..", Toast.LENGTH_SHORT).show();
updatePostButtonState();
Hype4DController controller = Hype4DController.getInstance();
controller.previewStack(getApplicationContext(), this, this.stack);
}
So I debugged on Toast.maketext() then it shows,
public Looper getMainLooper() {
return mBase.getMainLooper();
}
And warn that this loop is not in correct.
I think this is because of Toast maketext() function. Because other functions are working correctly.
So anyone please help me.
It seems that you run it in another thread, you must execute Toast in the main thread, you can try this:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Generating preview..", Toast.LENGTH_SHORT).show();
}
});
Toast.makeText() should only be called from Main/UI thread :
protected void previewStack() {
this.currentSubeditor.dataFromUIFields();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Generatingpreview..",Toast.LENGTH_SHORT).show();
}
});
updatePostButtonState();
Hype4DController controller = Hype4DController.getInstance();
controller.previewStack(getApplicationContext(), this, this.stack);
}
I'm trying to set the text of a TextView in my Android app using the following function:
#Override
public void onOSSubscriptionChanged(OSSubscriptionStateChanges stateChanges) {
if (!stateChanges.getFrom().getSubscribed() && stateChanges.getTo().getSubscribed()) {
new AlertDialog.Builder(this)
.setMessage("You have successfully subscribed to push notifications!")
.show();
// Get player ID and output to Main Activity
TextView playerIdView = findViewById(R.id.playerIdView);
playerIdView.setText(stateChanges.getTo().getUserId());
}
Log.i("Debug", "onOSPermissionsChanged: " + stateChanges);
}
This uses the OneSignal API to get the user's unique ID, which is returned as a string. After some debugging I realised the contents of a TextView can't be changed outside of the onCreate() method. However, the stateChanges parameter is required, which only exists within onOSSubscriptionChanged. Is there any way of getting around this?
EDIT: the error was elsewhere. stateChanges.getTo().getUserId() was returning null.
You need to set it on UI thread
playerIdView.post(new Runnable() {
public void run() {
playerIdView.setText(stateChanges.getTo().getUserId());
}
});
or
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
playerIdView.setText(stateChanges.getTo().getUserId());}
};
mainHandler.post(myRunnable);
you need to initialize you textview in your onCreateView() method and after that you can use that textView pretty much anywhere as long as you are in UI thread. So change your code to below:
Declare your textview globally so that you can use it anywhere in your activity instance.
TextView playerIdView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
playerIdView = findViewById(R.id.playerIdView);
}
and then in your onSSubscription method just do the following:
#Override
public void onOSSubscriptionChanged(OSSubscriptionStateChanges stateChanges) {
if (!stateChanges.getFrom().getSubscribed() && stateChanges.getTo().getSubscribed()) {
new AlertDialog.Builder(this)
.setMessage("You have successfully subscribed to push notifications!")
.show();
// Get player ID and output to Main Activity
playerIdView.setText(stateChanges.getTo().getUserId());
}
Log.i("Debug", "onOSPermissionsChanged: " + stateChanges);
}
Try This
runOnUiThread(new Runnable(){
#override
public void run() {
playerIdView.setText(stateChanges.getTo().getUserId());
}
})
i have a button with onclicklistener that download a picture from internet and update progress-bar in UI thread . when users click on the button for first time , it work correctly , but if the users click on the button for seconds &... when download is not completed , a duplicate process happens .how could i get rid of this problem?
Button btnDownload = (Button) findViewById(R.id.btndownload);
final TextView txtcaption = (TextView) findViewById(R.id.txtcaption);
final ProgressBar progress = (ProgressBar) findViewById(R.id.progress);
btnDownload.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
new Thread(new Runnable() {
OnProgressDownloadListener listener = new OnProgressDownloadListener() {
#Override
public void progressDownload(final int percent) {
new HANDLER.post(new Runnable() {
#Override
public void run() {
progress.setProgress(percent);
txtcaption.setText(percent + " %");
if (percent >= 100) {
txtcaption.setText("completed");
Toast.makeText(activity.this, "download completed", Toast.LENGTH_SHORT).show();
}
}
});
}
};
#Override
public void run() {
//my download manager
FileDownloader.download("address/file", DIR + "/file");
}
}).start();
}
});
}
An easy way to do this would be the following...
First, begin by declaring a thread...
Thread myThread
Then create a simple method that contains the thread you wish to execute when the button is pressed...
private void getPicture()
{
myThread = new Thread()
{
public void run()
{
// Place thread code here...
}
};
myThread.start();
}
Then you can do a simple check when the button is pressed and, if the thread is active, don't call the getPicture method...buttonDownload.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if (myThread.isAlive())
{
// Thread is alive, do not launch again
}
else
{
// Thread is not running so call method...
getPicture();
}
}
});
Have a Thread variable in your class that's initialized to NULL. In your onClickListener, check the value of that variable. If its null, start a new thread and save the value of that thread in the variable. If it isn't, ignore the button press or pop up a downloading toast. Remember to set the variable back to null when your thread is completed.
I'd highly recommend using an AsyncTask for this rather than a thread, it will be cleaner.
I have a button that I don't want to be clickable until a certain amount of time has run (say, 5 seconds?) I tried creating a thread like this
continueButtonThread = new Thread()
{
#Override
public void run()
{
try {
synchronized(this){
wait(5000);
}
}
catch(InterruptedException ex){
}
continueButton.setVisibility(0);
}
};
continueButtonThread.start();
But I can't modify the setVisibility property of the button within a different thread. This is the error from the LogCat:
10-02 14:35:05.908: ERROR/AndroidRuntime(14400): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Any other way to get around this?
The problem is that you can touch views of your activity only in UI thread. you can do it by using runOnUiThread function. I would like to suggest you to use
handler.postDelayed(runnable, 5000)`
You must update your view from UI-thread. What you are doing is you are updating from non-ui-thread.
Use
contextrunOnUiThread(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
}});
or use handler and signalize hand.sendMessage(msg) when you think is right time to update the view visibility
Handler hand = new Handler()
{
#Override
public void handleMessage(Message msg) {
/// here change the visibility
super.handleMessage(msg);
}
};
You can use the postDelayed method from the View class (A Button is a child of View)
here is simple answer i found
Button button = (Button)findViewBYId(R.id.button);
button .setVisibility(View.INVISIBLE);
button .postDelayed(new Runnable() {
public void run() {
button .setVisibility(View.VISIBLE);
}
}, 7000);