I am writing code for an inbox-like activity which has a button that leads to the messages. This button has a text field that counts how many messages are in the inbox.
My problem is that the button's text field is not changing when the number of messages changes. It is not a problem of the app not checking for updates, and the code with setText is being called with the correct number to update.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("onCreate", "Main");
// Checking if there is login
if (ParseUser.getCurrentUser() == null) {
navigateToLogin();
} else {
// Setting pointers for buttons.
// onClick methods follow.
askButton = (Button) findViewById(R.id.buttonAsk);
ansButton = (Button) findViewById(R.id.buttonAnswer);
inboxButton = (Button) findViewById(R.id.buttonCenter);
mUser = ParseUser.getCurrentUser();
updateInbox();
}
This is the method that checks for new messages and updates the button.
private void updateInbox() {
Log.v(TAG, "Updating inbox");
ParseQuery responses = new ParseQuery(ParseConstants.CLASS_ANSWER);
responses.whereMatches(ParseConstants.KEY_SENDER_ID, mUser.getObjectId());
try {
responsesCount = responses.count();
Log.v("responses count" ,""+responsesCount);
if (responsesCount > 0) {
inboxButton.setText(String.valueOf(responsesCount));
}
Log.v("InboxActivity","Label set to " + responsesCount);
} catch (ParseException e) {
Log.v("InboxActivity", e.getMessage());
}
}
updateInbox gets called correctly and in the correct moments, so I only added its code to make this as clean as possible. Here is the xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".MainActivity"
android:clickable="false"
>
<Button
android:layout_width="80sp"
android:layout_height="80sp"
android:id="#+id/buttonCenter"
android:layout_gravity="center"
android:layout_centerInParent="true"
android:textSize="30sp"
android:text=""
android:textColor="#color/black_overlay"
android:background="#drawable/greenbutton"/>
EDIT:
Hi all, thanks for the help. I figured out the problem and posted it as an answer. It was a logical error, nothing to do with Android.
try this:
inboxButton.post(new Runnable(){
#Override
public void run(){
inboxButton.setText(String.valueOf(responsesCount));
}
});
(responsesCount should be final)
Try below code
import android.widget.RemoteViews;
if (responsesCount > 0) {
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.my_layout); //where my_layout is the layout file where the button resides.
remoteViews.setTextViewText(R.id.button, "Set button text here");// where button is id of the button.
}
findViewById doesn't exist for a widget.
Below code will work for you
runOnUiThread(new Runnable() {
#Override
public void run() {
if (responsesCount > 0) {
inboxButton.setText(String.valueOf(responsesCount));
}
}
});
You may use AsyncTask for smoothness of app flow.
I realized that the text was only getting updated when the number of responses was > 0. The button was updating correctly otherwise so I had to put an else statement to make sure the button always got updated. I edited the question with the correct answer in comments.
responsesCount = responses.count();
Log.v("responses count" ,""+responsesCount);
if (responsesCount > 0) {
inboxButton.setText(String.valueOf(responsesCount));
///////////////////////////////////
// MY EDIT HERE
//} else{
// inboxButton.setText("");
///////////////////////////////////
Related
I have a button(button) and a textview(text) in my application. Before clicking on the button the textview text will always be "Start Search".But After clicking on the button , a function(scanning()) will be called. For executing the function it takes some times. So I want the texview text to be "Please wait" between the time after clicking the button and before getting the result of the function. And after getting the result of the function the textview text will be change to "Found" or "Not Found".
But problem is ,it never shows "please wait". After clicking on the button it shows "Start search" until getting the result of the function.
How to show "please wait" on the textview until it gets the result from the function after clicking on the button ??
Button button = (Button) findViewById(R.id.search);
TextView text = (TextView) findViewById(R.id.searchR);
text.setText("Start Search");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
text.setText("Please Wait");
boolean res=scanning();
if(res==true)
text.setText("Found");
else text.setText("Not Found");
}
});
XML Part:
<Button
android:id="#+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="60dp"
android:layout_marginLeft="60dp"
android:layout_marginTop="30dp"
android:text="Search"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/searchR"
android:layout_width="0dp"
android:layout_height="34dp"
android:layout_marginStart="97dp"
android:layout_marginLeft="97dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/search"
app:layout_constraintTop_toTopOf="parent" />
In the scanning part, I did some searching for BLE devices using UUID. If that device is found then I returned true otherwise false;
Introduce a small delay after you change the text to "Please Wait" and before calling scanning().
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
text.setText("Please Wait");
Handler delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
#Override
public void run() {
boolean res=scanning();
if(res) {
text.setText("Found");
}
else{
text.setText("Not Found");
}
}
},100);
}
});
Edit: Depending on your code, you may need to declare your variables as static or maybe global for this to work.
I found some mistakes in your code.
You are changing text of Button instead of TextView.
public void onClick(View v) {
text.setText("Please Wait");
boolean res=scanning();
if(res==true)
but1.setText("Found");
else but1.setText("Not Found");
}
Here
but1.setText
should be replaced with
text.setText
Your scanning method is returning result very fast, that's why you will not get Please Wait text.
Write external method for change text,
for example:
public void onClick(View v)
{
changeText("Please Wait");
boolean res = scanning();
if (res) // (res == true) is unnecessary, you can use like this
changeText("Found");
else changeText("Not Found");
}
private void changeText(string s)
{
text.setText(s);
}
I'm a new coder trying to figure out where I've gone wrong. My intent is to make an app with multiple buttons that each link to different websites. I've been using code from the web but am still not sure why it won't compile when I try adding uri.parse and am racking my brains looking for a solution.
So now I'm starting with a baseline example and trying to reverse engineer it to understand. I'm wanting the buttons to lead to a website instead of setting text. I've tried multiple solutions but none are working and I'm guessing you guys could answer this in your sleep. Thanks!
Update figured it out guys thanks!
Working java below
public class MainActivity extends Activity implements OnClickListener {
TextView tvOut;
Button btnOk;
Button btnCancel;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// find View-elements
tvOut = (TextView) findViewById(R.id.tvOut);
btnOk = (Button) findViewById(R.id.btnOk);
btnCancel = (Button) findViewById(R.id.btnCancel);
// assign listeners to buttons
btnOk.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// define the button that invoked the listener by id
switch (v.getId()) {
case R.id.btnOk:
// ОК button// Open Website
Intent intent;
try {
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com/yourPage"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (Exception e) {
Log.e("Exception Caught", e.toString());
}
break;
case R.id.btnCancel:
// Cancel button
Intent intent2;
try {
intent2 = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com/yourPage"));
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent2);
} catch (Exception e) {
Log.e("Exception Caught", e.toString());
}
break;
}
}
}
If you would like to keep the context of the webpage(s) within your app, you'll need to add a webview in your activity layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/webView"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
then add in onCreate:
final WebView webView = (WebView)findViewById(R.id.webView);
webView.loadUrl("http://www.google.com");
you'll need to add this to the manifest:
<uses-permission android:name="android.permission.INTERNET" />
this way you can keep things in control.. otherwise, you'll need to do it with an Intent. simple example and docs for that are here:
http://developer.android.com/reference/android/webkit/WebView.html
My application is Enter an amount, calculate the amount and display the amount.
I am using Android SDK 16. When i enter the amount and click on the calculate button i am getting the
SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length.
My Activity class is
public class ChapterTwo extends Activity {
public static final String tag = "Chapter 2";
static{
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
#SuppressWarnings("unused")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_two);
final EditText mealpricefield = (EditText) findViewById(R.id.mealprice);
final TextView answerfield = (TextView) findViewById(R.id.answer);
final Button button = (Button) findViewById(R.id.calculate);
button.setOnClickListener(new Button.OnClickListener() {
public void onClickView(View v) {
try {
Log.i(tag, "onClick Invoked");
// grab the meal price from UI
String mealprice = mealpricefield.getText().toString();
Log.i(tag, "meal price is [" + mealprice + "]");
String answer = "";
// check to see if meal price contains $
if (mealprice.indexOf("$") == -1) {
mealprice = "$" + mealprice;
}
float fmp = 0.0F;
// get currency formatter;
NumberFormat nf = java.text.NumberFormat
.getCurrencyInstance();
// grab the input meal price
fmp = nf.parse(mealprice).floatValue();
// let's give a nice tip
fmp *= 1.2;
Log.i(tag, " Total meal price Unformatted is [" + fmp + "]");
// format our result
answer = " Full Price, Including the 20% Tip is "
+ nf.format(fmp);
answerfield.setText(answer);
Log.i(tag, " On Click Complete");
} catch (java.text.ParseException e) {
Log.i(tag, "Parse Exception caught");
answerfield.setText("Failed to Parse the Exception");
}
catch (Exception e) {
Log.e(tag, "Failed To calculate the tip" + e.getMessage());
e.printStackTrace();
answerfield.setText(e.getMessage());
}
}
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}}
My Layout is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Chapter 2 Android Tip Calculator"
tools:ignore="HardcodedText" />
<EditText
android:id="#+id/mealprice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text">
<requestFocus />
</EditText>
<Button
android:id="#+id/calculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Calculate Tip" />
<EditText
android:id="#+id/answer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" />
I am getting the following error in the log cat
10-23 20:19:26.232: E/Trace(699): error opening trace file: No such file or directory (2)
10-23 20:19:27.092: D/gralloc_goldfish(699): Emulator without GPU emulation detected.
10-23 20:19:33.262: W/IInputConnectionWrapper(699): showStatusIcon on inactive InputConnection
10-23 20:24:22.106: I/Choreographer(699): Skipped 30 frames! The application may be doing too much work on its main thread.
10-23 20:27:52.824: I/Choreographer(699): Skipped 37 frames! The application may be doing too much work on its main thread.
10-23 20:31:13.323: E/SpannableStringBuilder(699): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
10-23 20:31:13.323: E/SpannableStringBuilder(699): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
10-23 20:31:32.552: I/Choreographer(699): Skipped 35 frames! The application may be doing too much work on its main thread.
10-23 20:39:44.723: I/Choreographer(699): Skipped 63 frames! The application may be doing too much work on its main thread.
You should declare all the views in main class and initialize them in onCreate() method:
public class ChapterTwo extends Activity {
public static final String tag = "Chapter 2";
EditText mealpricefield;
TextView answerfield;
Button button;
.
.
.
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_two);
mealpricefield = (EditText) findViewById(R.id.mealprice);
answerfield = (TextView) findViewById(R.id.answer);
button = (Button) findViewById(R.id.calculate);
.
.
.
}
Also the code that you have placed in onClickView(View v) should be inside onClick(View v) that you have below in your code:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
Is there more code other than the one you posted?
Here are couple things I noticed:
Your code won't do anything when you press the button since you are not doing anything in the onClick(View v) method as pointed above. You have an onClickView(View v) function, which no one calls. You should move your code from onClickView() to onClick() and just get rid of the onClickView() method (or you can just call onClickView from onClick function).
If you move the code as noted above, your code will work, I even tested it myself just now to double check. (You are missing a </LinearLayout> tag in the copy-paste code above but I assume you had it).
The error log you posted shows an error from SpannableStringBuilder. But you are not using SpannableStringBuilder at all anywhere in your code, so either a) you have some other code or b) this error has nothing to do with your code.
What happens when you press the button? Does the application crash? What values are you using for testing when you see the issue? Is there any other log in the log that has your tag or application name? The log you posted doesn't show any force-close logs or any errors associated with your application.
On second thought, are you saying that your problem is that when you press the Calculate button, nothing happens? So you assumed you had an error and just thought that the error you saw in the log was the reason your code didn't work? If that's the case, all you have to do is just move the code block in onClickView() into onClick() and get rid of onClickView(). The error log is from some other program that has nothing to do with your code.
At a glance, this may be your problem.
Log.i(tag, " Total meal price Unformatted is [" + fmp + "]");
fmp is a float... you are adding it to a string.
comment this line out and see if it works.
Quite new to coding for android but this issue has me tearing my hair out because it seems to make no sense at all...
I have an activity with four form elements in the layout: a CheckBox, two EditTexts and a Button.
When the user presses the button, it saves the content of the EditTexts as two preference values.
When the user presses the checkbox, it does the following:
If the checkbox is checked, load the preferences and store them into two variables.
Check if either of those variables contain empty strings after trimming them.
If so, show an error message, otherwise show a success message.
Essentially, the two text fields are used to set a pair of preferences which must not be empty when the checkbox is clicked.
It seems to work fine if I click the checkbox before pressing the button - error message or success message shown as appropriate.
If I press the save button and then click the checkbox, it always shows the success message regardless of the preferences.
Code follows (trimmed from the program as a whole)...
layout.xml
<CheckBox android:id="#+id/cboxActive" android:text="Click me!" android:onClick="toggleActive" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<EditText android:id="#+id/editFrom" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="phone"><requestFocus /></EditText>
<EditText android:id="#+id/editTo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="phone"></EditText>
<Button android:id="#+id/btnSave" android:onClick="savePrefs" android:text="Save" android:layout_width="120dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" />
</LinearLayout>
main class:
public class AutoMessengerActivity extends Activity
{
SharedPreferences settings;
CheckBox cboxActive;
EditText editFrom, editTo;
boolean active;
String from, to;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editFrom = (EditText) findViewById(R.id.editFrom);
editTo = (EditText) findViewById(R.id.editTo);
showPrefsInUI();
}
private void loadPrefs()
{
//Load preferences
settings = getPreferences(MODE_PRIVATE);
from = settings.getString("from", "");
to = settings.getString("to", "");
}
private void showPrefsInUI()
{
loadPrefs();
//Set UI elements to preference values
editFrom.setText(from);
editTo.setText(to);
}
public void savePrefs(View view)
{
SharedPreferences.Editor editor = settings.edit();
editor.putString("from", editFrom.getText().toString());
editor.putString("to", editTo.getText().toString());
editor.commit();
Toast.makeText(this, "Prefs saved!", Toast.LENGTH_SHORT).show();
}
public void toggleActive(View view)
{
if (cboxActive.isChecked())
{
loadPrefs();
//This toast is for debugging
//It shows the correct data in all circumstances...
Toast.makeText(this, "F: " + from + " T: " + to, Toast.LENGTH_SHORT).show();
//This is the part that seems to fail if you save then click checkbox
if (from.trim() == "" || to.trim() == "")
{
Toast.makeText(this, "Error - Prefs not saved", Toast.LENGTH_LONG).show();
cboxActive.setChecked(false);
}
else
{
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "Unchecked!", Toast.LENGTH_SHORT).show();
}
}
}
Hopefully that code gives an idea of the problem and allows it to be replicated...
Oh god, how silly of me - Urban and jcxavier hit the nail on the head... I forgot about that damn annoying quirk of Java! Changed the line to
from.trim().equals("") || to.trim().equals("")
And it works fine!
For what it's worth, that HAD actually crossed my mind briefly, but it was 2am when I tried equals and I got confused about requiring an Object as the parameter and ended up specifying null rather than "" - which didn't work...
I working on a chat app.
Whenever I submit or receive a text message, I append them to the chatbox.
When the list get longer, I need to scroll down to see them.
How can I make it to autoscroll to the newly append text?
<ScrollView
android:id="#+id/scrollView01"
android:layout_width="fill_parent"
android:layout_height="100px" >
<TextView
android:id="#+id/txtChat"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>
</ScrollView>
//
SendMsg.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
String name = txtName.getText().toString();
String message = txtMessage.getText().toString();
if (message.length() > 0) {
sendMsg(name, message);
String myMessage = message + "\n";
tvChat.append(myMessage);
}
else
Toast.makeText(getBaseContext(),
"Please enter both name and message.", Toast.LENGTH_SHORT).show();
}
});
I had the same issue, this is what I'm using:
//delay must be expressed in milliseconds. For 3 seconds, delay = 3000
private void scrollToBottom(int delay) {
// If we don't call fullScroll inside a Runnable, it doesn't scroll to
// the bottom but to the (bottom - 1)
mChatBox.postDelayed(new Runnable() {
public void run() {
mChatBox.fullScroll(ScrollView.FOCUS_DOWN);
}
}, delay);
}
where mChatBox is:
ScrollView mChatBox;