AsyncTask OnPostExecute not updating TextView - android

I have an AsyncTask running. I have a TextView that I mimic the message a Toast initially produces.
I want to clear the TextView upon success in OnPostExecute but it not doing so. The task complete Toast works fine. How do I set the TextView in the OnPostExecute to blank? The user is still on the display screen where the TextView is.
Code is as follows for an error condition:
#Override
protected void onPostExecute(Void result)
{ FetchingImage=0;
if(webLoadError>0)
{
TextView text = (TextView) findViewById(R.id.textView2);
String temp=" ";
text.setText(temp);
Toast.makeText(getApplicationContext(), "Image not available from the internet.\nDefault or last image loaded.\nTry again later.",Toast.LENGTH_LONG).show();
}
}

Try something like:
((TextView) findViewById(R.id.textView2)).setText("");
EDIT:
try making a variable outside the onCreate like TextView text; and then inside the onCreate put: text = (TextView) findViewById(R.id.textView2);
and then just put text.setText(""); inside the onPostExecute method.
See if that works.

I know this thread is old, but I think I found the solution (at least it worked for me), perhaps it help others:
I had a view with 3 textviews with default values receiving values from a webservices from "doInBackground" method of a AsyncTask and later changing the text in them on "onPostExecute" method. The issue was that only one of the three textviews was showing the new text from the ws in the first execution of code (it's a simple application implementing the Zxing barcode reader reading a barcode from a product and obtaining the price from a webserver, anyway), the next executions (after the app is opened) was updating the three textviews normally.
So I noticed that the only textview that was updating its value in the first execution had its parameter "android:textIsSelectable" = true, the other two was false. Bingo, changing this parameter to true in the other 2 textviews solved the issue.

Related

getLineCount of TextView with Runnable not working properly in Adapter

I am developing an Android application. My app has news feed list like Facebook. I am setting readmore feature if the text of TextView is too long for each post. I am using ExpandableTextView for readmore feature. But it is ok.
Then problem is with getting line count of TextView. I need to know the line count after I set the text to TextView because I need to toggle the visibility of Read more button. But getLineCount is not working well.
In the bindViewHolder of Recycler adapter, I set the text to TextView like this:
viewHolder.tvTitle.setText(post.getTitle());
viewHolder.tvTitle.post(new Runnable() {
#Override
public void run() {
Log.i("LINE_COUNT_"+String.valueOf(position),String.valueOf(viewHolder.tvTitle.getLineCount()));
if(viewHolder.tvTitle.getLineCount()>=3)
{
viewHolder.tvReadmore.setVisibility(View.VISIBLE);
}
else{
viewHolder.tvReadmore.setVisibility(View.GONE);
}
}
});
As you can see, I am using runnable because getLineCount() of TextView always returns 0 if I do not use it. But when I run my code and see my app, getLineCount() is working only for first 2 or 3 items. Not working for the rest of the items. I log the line count in the code. This is what I get in logcat. See the screenshot below.
As you can see in the logcat, it is returning value only for the first 2 items. For the rest of items, it always returns 0. Actually, all TextViews in the list has text line at least one. Some have 4 or 5. But it is not working. The runnable does not work well in RecyclerView Adapter? How can I fix my code to get the correct line count of textview in adapter?

Displaying an array of objects, one at a time through a single dialog... instead of several dialogs

In my application I have a list of questions stored in an ArrayList, and I want to display a dialog that shows one question, and then continues to the next one after the question is answered. The way that I'm currently doing it (iterating through a loop) hasn't been working because it just layers all of the dialogs on top of one another all at once which causes a host of other issues. What I'm looking for is a way to still iterate through the questions, but just change the layout of the dialog each time until it has finished each question in the list. Can anyone give me a good pointer for how to get this going?
You can make a function that takes title and message as parameters and shows a dialog.
showDialog(String title, String message){ // Show dialog code here}
Within that dialog's answer button's listener call another function (showQuestion(currentQuestion)) that iterates the arrayList till it is over
int currentQuestion=0;
ArrayList<QuestionObject> questionList;
showQuestion(int i){
if(i<questionList.size()){
showDialog(questionList.get(i).getTitle,questionList.get(i).getMessage);
currentQuestion++;
}else{
//quiz is over
}
}
I assume you mean that you just want to change 1 single layout(created within XML i.e main.xml). In order to do this, make sure that the class your working on is pointing to that layout. From there (assuming your using an Event listener for when the user submits an answer) you can change do as you want by the following:
TextView txt = (TextView) findViewById(R.id.textView); // references the txt XML element
and in your Event listener, if the answer is correct then change(Have i be a global variable thats initially set to 0).
if(i<arrayList.size()){
txt.setText(arrayList.get(++i));
}else{
txt.setText("You Finished");
}
From there, in the else statement, you can change arrayLists and reset i to 0;
If you are trying to use the positive, neutral, and negative buttons; then you may have problems with multiple dialogs. Try defining a customized layout with your own TextViews, ListViews, and Buttons. You can implement listeners and everything else like a regular layout. Then just pass your customized layout to the dialog through AlertDialog.Builder.setView().
PS If you include code examples of what you are currently doing we can provided answers that are less vague.

Android displaying items on screen on that come from a remote db

I am facing an issue of having a screen which gets an id from the SharedPreferences and then I call a remote database, and then I have to display that data on the screen.
Is it possible to do that with ViewText or is there another way to place text on the screen after a remote db call is made?
Whats the best way to do that and how do I accomplish it?
Thanks!!
Use a loader for your db call. Once the data has loaded use onLoadFinished to either add a TextView to your layout or replace the text in an existing layout.
My suggestion would be to create a TextView in your layout in xml so that you can position it exactly as you wish, then replacing the text after your database call using myTextView.setText(databasetext)
The way you display data from a database is completely independent of the way you're getting that data. If it's simply text you need to display, then a TextView seems to be a logical view element to use.
In simple terms, the steps you should be taking would likely be:
Get ID from SharedPreferences
Query database with ID for result
Pass the result to your view layer
Use a TextView to display the result
It's best (and required since 4.0) to make network calls in a thread separate from the UI thread. The best way is probably using an AsyncTask. For example:
private class GetDbItemTask extends AsyncTask<Integer, Void, MyDbItem> {
protected MyDbItem doInBackground(Integer... ids) {
return mDbService.load(ids[0]);
}
protected void onPostExecute(MyDbItem result) {
mTextView.setText(result.toString());
}
}
Have you tried a custom alert dialog this link?
This allows you to have a textview on your screen without changing your activity.
I hope I answered this correctly since you ask
"Is it possible to do that with ViewText or is there another way to
place text on the screen after a remote db call is made?".
Then there is the option of refreshing the screen using onResume() on the activity lifecycle.
The logic would that I would use is to build your screen in XML and have a Textview named myTextView
in your activity declare a Textview
TextView name_field;
String name;
....
.
.
.
//call my database info
//this example get a variable and pass it into String variable name and then display it in your text view
name_field = (TextView) findViewById(R.id.myTextView);
name_field.setText(name);

"Force Close" Error on declaring TextView and ToggleButton

Well basicly I have a textview and when the application is created it sets a string as the textviews text not hard, but I get a force close error when I run the app on my phone.
TextView sdcard=(TextView)findViewById(R.id.sd_textview);
sdcard.setText(R.string.not_mounted);
Then I have a error on a togglebutton also
ToggleButton silent=(ToggleButton)findViewById(R.id.silentbutton);
silent.setChecked(false);
And I have errors for all my other buttons/textviews can anyone help, please?!
EDIT:
I cant post pics because I am a new member, :(
Link to imgshack http://imageshack.us/photo/my-images/849/unledggp.png/
If code for the whole textview snippet.
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_UNMOUNTED)) {
TextView sdcard=(TextView)findViewById(R.id.sd_textview);
sdcard.setText(R.string.not_mounted);
}
OnCreate Function
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
checkSD();
checkRing();
checkWifi();
checkBt();
}
Look for all instances of sd_textview and make sure the one that you're trying to reference is a TextView. If you want more clarity you can debug your code and see what object is actually being returned by not casting into a TextView:
View sdcard = findViewById(R.id.sd_textview); //debug this
//you can also log the View object to see the type
Log.d("Test", "" + sdcard);
Looking at your error log (assuming its the right error log) you have a ClassCastException in the checkWifi method. Edit your question and include ALL of the onCreate method and all of the checkWifi method, but I expect you are using the same id for multiple views.
Two things I can think of (although seeing more code would help).
Make sure you have called setContentView(R.layout.main) (or whatever your layout file is called). Do this BEFORE any attempt to use findViewById(...).
Secondly sdcard.setText(R.string.not_mounted); in this statement R.string.not_mounted is a resource ID (int) and not a string. You would need to use...
sdcard.setText(getString(R.string.not_mounted));

How to correctly use TextSwitcher in ListView?

My TextSwitcher for each record in ListView should display first value (text1) and then another value (text2), then first value again and so on. It should happen only if text2 not empty. Otherwise text1 should be always shown (without any changes and animation).
I've created Runnable(), which changes boolean variable (time2) to then call items.notifyDataSetChanged(). It works as expected and in result setViewValue() for my ListView is called.
Here is the code:
items.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int viewId = view.getId();
switch(viewId) {
case R.id.timetext:
TextSwitcher itemTime = (TextSwitcher) view;
if (itemTime.getChildCount() != 2) {
itemTime.removeAllViews();
itemTime.setFactory(new ViewSwitcher.ViewFactory() {
#Override
public View makeView() {
TextView t = new TextView(MyActivity.this);
t.setTextSize(18);
t.setTypeface(null, Typeface.BOLD);
t.setTextColor(Color.WHITE);
return t;
}
});
itemTime.setAnimateFirstView(true);
itemTime.setInAnimation(AnimationUtils.loadAnimation(MyActivity.this,
R.anim.push_up_in));
itemTime.setOutAnimation(AnimationUtils.loadAnimation(MyActivity.this,
R.anim.push_up_out));
}
if (!text2.equals("")) {
if (!time2) {
itemTime.setText(text1);
} else {
itemTime.setText(text2);
}
} else {
itemTime.setCurrentText(text1);
}
return true;
}
return false;
}
} );
It works almost as expected. With one minor item - when text2 should be shown, it changes displayed value to some other value first (from another record!) and then animation is played. Change of text2 to text1 happens correctly.
My understanding that the reason is the following - before displaying text2, all views of itemTime are removed and hence it is recreated and that is why some other value is shown for a second. But why does it show value from some other record?
Actually text2 and text1 are values from the database, for ex.
text2 = cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_TIME_2)), probably, something is wrong here and setViewValue called with wrong parameters?
Upd. text1 and text2 are read from the database at setViewValue. Here is example of the full code:
itemTime.setText(cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_CLOSE_TIME_1)) + " - " + cursor.getString(cursor.getColumnIndexOrThrow(DbAdapter.KEY_OPEN_TIME_1)));
I know this might not answer the question directly, but I'm going to respond to your comment about creating a Runnable() to do the work of switching for you because I suspect that it is probably messing with your data (hard to tell when you cant see the full code).
I advise you to use a ViewFlipper instead of a TextSwitcher. The reason for doing that is that once you added the TextView's inside your ViewFlipper, you can just set your flip interval and then start the flipping and it will do it automatically for you.
As simple as this:
/* Add your items to your ViewFlipper first */
myViewFlipper.setFlipInterval(1000); //time in millseconds
myViewFlipper.startFlipping();
In your current method that you described, when you call items.notifyDataSetChanged() you incur a huge performance hit because all items of your database are going to be re-read and your list will be "re-drawn" again. You should only do that if your actual data really changed rather than using it to switch between text that you already have and doesn't change from creation time.
As a nice surprise, you might notice that your problem goes away because you don't have to re-read everything from you DB again and reduces the chances of mix-up of item1 and item2 since you will only need to read them once when the row is created in your ListView
Just my 2 cents.
Let me know how it goes.
I think I see what's going on here, and it's because of the way ListView works.
ListView recycles all of its views internally so that you only have as many views created as can be displayed on the screen. However, this also means that when you bind values to a view in your setViewValue method, you are not always given the view that was in the same position in the list before.
Say you have three list items: itemA, itemB, itemC in that order. Each contains text1, text2, and text3 respectively at first.
When you call items.notifyDataSetChanged(), ListView recycles all those list items however it feels like, so you may get a new order of itemC, itemA, itemB; and the text would then read text3, text1, text2.
As a result, when you change the text of the first list item to "text2", you will in fact see "text3" change to "text2" instead of a transition from "text1" to "text2" like you are expecting.
Are text1 and text2 stored in the resources file (res/values/strings.xml)? If so, Android will sometimes confuse variables. Simply running Project > Clean on this project may fix the problem.
This worked for me :
myViewFlipper.setFlipInterval(1000);
myViewFlipper.startFlipping();

Categories

Resources