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?
Related
I am Android developer .I am used in json parser . i have to stored all data in Array List .What are the issue means i got custom id .They given 0 and 1 value passed.When i will get 0 means add button visible otherwise 1 will get in means custom button visible.How to check it in get View method.
I have added Array List .
just use the condition something like below
if (yourvalue.equals("0")
{
button.setVisibility(View.VISIBLE);
}
else
{
button.setVisibility(View.GONE);
}
Use the following code inside your get view method:
button.setVisibility((value==0)?View.VISIBLE:View.GONE);
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.
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.
I have a list with images and text, Text change in every 1-2 second .I have a custom adapter class which extends the BaseAdpater class. I want to update only the textview in listrow as data change.
I am using broadcast receiver which register when activity start and give back result in every 2 second which i want to display in listview.
The problem is when i call notifyDataSetChanged the whole listview get refreshed including icons and another textview and hang for 1-2 second. There is a big performance issue.
please give suggestion how can i handle that?
you can try this:
private void updateSingleRow(int listrow, String newText){
View view = yourListView.getChildAt(listrow - yourListView.getFirstVisiblePosition());
TextView yourText = (TextView) view.findViewById(R.id.yourId);
yourText.setText(newText);
}
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();