Automatic scrolling a text view after appending text in Android - java

I'm trying to make the content of a textview to automatically scroll to the bottom at the most recent text appended. I tried many ways from many post but seems there's no way to make it work. I trie also different layout_wheight and width parameters and so on. The silly thing is that I already made it in the past and it worked, but now using the same set up it is not.
Here's my latest xml code:
<TableRow
android:id="#+id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.5"
android:weightSum="2">
<ScrollView
android:id="#+id/askScv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="vertical">
<TextView
android:id="#+id/askTxv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:maxLines="99999"
android:scrollbars="vertical"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
</ScrollView>
<ScrollView
android:id="#+id/answerScv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="vertical">
<TextView
android:id="#+id/answerTxv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:maxLines="99999"
android:scrollbars="vertical"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
</ScrollView>
</TableRow>
and the Java one:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mQuestionEdt = (EditText) findViewById(R.id.questionEdt);
mAnswerTxv = (TextView) findViewById(R.id.answerTxv);
mAnswerTxv.setMovementMethod(new ScrollingMovementMethod());
mAnswerScv=(ScrollView)findViewById(R.id.answerScv);
mAnswerScv.fullScroll(View.FOCUS_DOWN);
mAskTxv=(TextView) findViewById(R.id.askTxv);
mAskTxv.setMovementMethod(new ScrollingMovementMethod());
mAskScv=(ScrollView)findViewById(R.id.askScv);
mAskScv.fullScroll(View.FOCUS_DOWN);
mAskBtn = (ImageButton) findViewById(R.id.askBtn);
mAskBtn.setOnClickListener(this);
mStartBtn = (ImageButton) findViewById(R.id.startBtn);
mStartBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Bundle result;
if (view.equals(mAskBtn)) {
result=mAnsweringMachine.answer(mQuestionEdt.getText().toString());
mAskTxv.append("\n" + mQuestionEdt.getText().toString());
mAskScv.smoothScrollTo(0,mAskTxv.getBottom());
mAnswerTxv.append("\n" + result.getString(AnsweringMachine.DIALOGUE_RESULT));
mAnswerScv.smoothScrollTo(0,mAnswerTxv.getBottom());
} else if (view.equals(mStartBtn)) {
result = mAnsweringMachine.runStartingPrompt();
mAnswerTxv.append(result.getString(AnsweringMachine.DIALOGUE_RESULT));
//mAnswerScv.fullScroll(View.FOCUS_DOWN);
}
}
And here's my old working code, xml:
<ScrollView
android:id="#+id/terminalScv"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/terminalTxv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textAppearance="?android:attr/textAppearanceLarge" />
</ScrollView>
and Java one:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_terminal);
terminalTxv=(TextView) findViewById(R.id.terminalTxv);
terminalScv=(ScrollView) findViewById(R.id.terminalScv);
terminalScv.fullScroll(View.FOCUS_DOWN);
}
#Override
protected void onBtDataReceived(int[] data) {
super.onBtDataReceived(data);
String out=String.valueOf(terminalTxv.getLineCount())+" - ";
for (int x=0;x<data.length-1;x++){
out+=data[x];
out+=" ";
}
out+="\n";
terminalTxv.append(out);
terminalScv.smoothScrollTo(0, terminalTxv.getBottom());
}
Hope somebody can make me understand this enigma....
Thanks!

In the XML for the textView element I would try to add:
android:gravity="bottom"
Also are you sure you need to specify android:scrollbars="vertical" in both scrollview and textview? In addition, I noticed the difference between old working version is that it doesn't uses setMovementMethod() - personally I would use this method without scrollview, but since you already have scroollview I don't see a reason why would you need it...

Related

getWidth() returns 0 even after applying a workaround

My java code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
final TextView textView = (TextView) findViewById(R.id.text1);
final Button button = (Button) findViewById(R.id.button1);
button.post(new Runnable() {
#Override
public void run() {
int buttonWidth = button.getWidth();
int textWidth = textView.getWidth();
button.setWidth(buttonWidth-textWidth);
}
});
My xml views:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Timer"
android:textSize="16sp"/>
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="+5"/>
I'm using the second way as described in this answer.
What I want to do is have the button fill the entire width with just enough space for the textView. I've been learning Android for the last few months only so it'll be helpful if you could explain in a lucid manner.
you can use a linearlayout with your button having a weight of 1 and your textview to wrap content.
try this:
<?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="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some text" />
</LinearLayout>
Use the addOnGlobalLayoutListener instead from the solution you linked, that usually works for me when I see this issue.
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT > 16) {
myView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
else {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
myView.getWidth();
}
});

Moving a view from a viewgroup to another one

activity_main.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:longClickable="false"
android:orientation="vertical"
android:weightSum="16"
android:animateLayoutChanges="true">
<LinearLayout
android:id="#+id/ly_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="Indonesia"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="English"/>
</LinearLayout>
<LinearLayout
android:id="#+id/ly_ll2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="Spain"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="Brazil"/>
</LinearLayout>
</LinearLayout>
MainActivity.java:
public class MainActivity extends Activity {
LinearLayout llLayout;
LinearLayout llLayout2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
llLayout = (LinearLayout) findViewById(R.id.ly_ll);
llLayout2 = (LinearLayout) findViewById(R.id.ly_ll2);
for(int i=0;i<llLayout2.getChildCount();i++){
View views = llLayout2.getChildAt(i);
views.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addedViewTarget(v);
}
});
}
}
public void addedViewTarget(View view){
llLayout2.removeView(view);
llLayout.addView(view);
}
}
I have a case where the case is to move the view from viewgroup to another viewgroup. The problem is when I delete a code llLayout.addView(view); it's no problem and the view is successfully erased, but when I want to add a view to llLayout always an error like this "The specified child already has a parent. You must call removeView() on the child's parent first". So, I want to move the view in llLayout2 to llLayout when clicked, are you guys the best solution for this case?
oO yes you are right i tried your code and dose not works
i tried few things and i came up with this weird solution :|
public void addedViewTarget(final View view) {
ViewGroup vg = ((ViewGroup) view.getParent());
vg.removeView(view);
view.postDelayed(new Runnable() {
#Override
public void run() {
llLayout.addView(view);
}
},1000 );
}
i don't know why your code is not working and i dont know why this code is working but I have this hypothesis when you are saying remove View its takes some Time maybe in other thread and when your trying add the view to other ViewGroup instantly it raise error because removing task not complete yet
Try this
if(view.getParent()!=null)
((ViewGroup)view.getParent()).removeView(view);
llLayout.addView(view);

Changing font style / format inside a string array in android

I'm currently working on my first app - no experience in java or android so please have patience with me :)
In the app I'm using a custom list view with text only and 4 text views in each list item/container.
With these text views I'm using a custom font (applied using java in the listview adapter).
The font is loaded in assets/fonts
Text is fetched from a string array in strings.xml
I have figured all this out so far using all the Q&A's on this website however can't seem to find a solution for the following...
I want to change the style of my text (which has the custom font) during the paragraph/sentence. I want to highlight specific words or phrases in Italics for example:
I enjoy coding.
The word enjoy is Italics where the rest of the sentence is in Regular format.
I've seen plenty of guides on how to change a whole class or text-view into italics or bold styles however not specific portions of text.
So far the only possible solution I've found is to try italic markers in strings.xml however this doesn't seem to work and I don't know why
I'm assuming what I need to do is:
1. load the italic version of the font separately in java
2, then write some code that tells the app to apply this font to specific portions of text, either in strings xml or some other way. (preferably in strings xml as there is alot of text)
Your help is much appreciated, Many thanks in advance.
Apologies if my explanation is too brief its my first post.
my code: (if you need anything else let me know.)
the main activity
custom listview adapter
main xml layout
row xml layout
public class WirdActivity extends Activity {
MediaPlayer mp;
String[] Arabic;
String[] Transliteration;
String[] Translation;
String[] Number;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wird);
Resources res=getResources();
Arabic=res.getStringArray(R.array.wirdarabic);
Transliteration=res.getStringArray(R.array.wirdtransliteration);
Translation=res.getStringArray(R.array.wirdtranslation);
Number=res.getStringArray(R.array.wirdnumber);
mp = MediaPlayer.create(this, R.raw.wird);
Button playwird = (Button) findViewById(R.id.playwird);
playwird.performClick();
playwird.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mp.start();
}
});
ImageButton pausewird = (ImageButton) findViewById(R.id.pausewird);
pausewird.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mp.pause();
}
});
ListAdapter theAdapter = new Wirdadapter(this, Arabic, Transliteration, Translation, Number);
final ListView wirdlist = (ListView) findViewById(R.id.wirdlist);
wirdlist.setAdapter(theAdapter);
}
#Override
protected void onDestroy() {
super.onDestroy();
mp.stop();
}
class Wirdadapter extends ArrayAdapter<String> {
private AssetManager assets;
Typeface font = Typeface.createFromAsset(getContext().getAssets(),
"fonts/trado.ttf");
Typeface font2 = Typeface.createFromAsset(getContext().getAssets(),
"fonts/JaghbUni-Rom.ttf");
String[] titleArray;
String[] descriptionArray;
String[] subtitleArray;
String[] numberArray;
public Wirdadapter(Context context, String[] titles, String[] desc,String[] sub,String[] num) {
super(context, R.layout.row_layout_3, R.id.textview2,titles);
this.titleArray=titles;
this.descriptionArray=desc;
this.subtitleArray=sub;
this.numberArray=num;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater theInflater = LayoutInflater.from(getContext());
View theView = theInflater.inflate(R.layout.row_layout_3, parent, false);
TextView Arabic = (TextView) theView.findViewById(R.id.textview2);
TextView Transliteration = (TextView) theView.findViewById(R.id.transliteration);
TextView Translation = (TextView) theView.findViewById(R.id.translation);
TextView Number = (TextView) theView.findViewById(R.id.number);
Arabic.setText(titleArray[position]);
Transliteration.setText(descriptionArray[position]);
Translation.setText(subtitleArray[position]);
Number.setText(numberArray[position]);
Arabic.setTypeface(font);
Transliteration.setTypeface(font2);
Translation.setTypeface(font2);
Number.setTypeface(font2);
return theView;
}
<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="5000pt"
android:background="#drawable/gradient_background3"
tools:context=".WirdActivity"
android:orientation="vertical"
android:focusableInTouchMode="true"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#927e68"
>
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="#string/wird_title"
android:textSize="16sp"
android:padding="10dp"
android:layout_marginStart="5dp"
android:textColor="#ffffff"
android:id="#+id/wirdtitle"
/>
<ImageButton
android:layout_height="25dp"
android:layout_width="30dp"
android:id="#+id/pausewird"
android:background="#drawable/pause"
android:clickable="true"
android:layout_gravity="center"
android:layout_marginEnd="65dp"
android:layout_alignParentEnd="true"
android:layout_alignBottom="#+id/playwird"
/>
<Button
android:layout_height="25dp"
android:layout_width="25dp"
android:id="#+id/playwird"
android:background="#drawable/play"
android:clickable="true"
android:layout_alignBottom="#id/wirdtitle"
android:layout_marginEnd="15dp"
android:layout_marginBottom="17.5dp"
android:layout_alignParentEnd="true"
/>
</RelativeLayout>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="515dp" >
<LinearLayout
android:id="#+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitStart"
android:src="#drawable/w1"
android:id="#+id/wirdhead"
android:adjustViewBounds="true"/>
<ListView
android:layout_width="match_parent"
android:layout_height="4100dp"
android:id="#+id/wirdlist"
android:gravity="right"
android:divider="#f1f1f1"
android:dividerHeight="0.5dp"
>
</ListView>
</LinearLayout>
</ScrollView>
</LinearLayout>
<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"
tools:context=".MainActivity">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/number"
android:textSize="10sp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp"
android:textColor="#4c4c4c">
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/textview2"
android:textSize="30sp"
android:padding="15dp"
android:layout_alignParentRight="true"
android:layoutDirection="rtl"
android:gravity="right"
android:textColor="#4c4c4c">
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/transliteration"
android:textSize="15sp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingBottom="5dp"
android:textColor="#4c4c4c">
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/translation"
android:textSize="15sp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingBottom="15dp"
android:textColor="#4c4c4c">
</TextView>
</LinearLayout>
You can either use the SpannableStringBuilder class or the Html.fromHtml() method. The simpler one is the Html.fromHtml() method.
Example:
tView.setText(Html.fromHtml("I <i>enjoy</i> coding"));
The Html.fromHtml() method basically returns a SpannableString, but I usually find it easier than using the SpannableStringBuilder class.
That being said, if you want to modify the String dynamically, then you need to use the SpannableStringBuilder class.
Note:
I have not tried the fromHtml() method on an XML string resource, but do try it and share the results.
PS:
If you are really curious about SpannableString class, go here for a simple example or here for the full documentation.

OnClickListener not working when i click on text

when click on text nothing happened. there is not exception in CatLog or showing any error. i checked Manifest file and c_programs_start_51_100.xml file but i found nothing wrong still struggling find out the problem. The function Onclick() doesn't executed at single when i check in CatLog. please help me resolve the problem.
Thanks in advance.
public class C_Programs_Start_51_100 extends Activity implements View.OnClickListener{
TextView textViewC51;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.c_programs_start_51_100);
textViewC51 = (TextView) findViewById(R.id.textView51);
textViewC51.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Log.d("press", "second" + view.getId());
switch(view.getId()) {
Log.d("press", "first");
case R.id.textView51:
Log.d("press", "first");
Intent intent51 = new Intent(C_Programs_Start_51_100.this, C_Programs_P51.class);
startActivity(intent51);
Log.d("press", "second");
break;
}
}
}
// Here is my xml file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".First" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/table_vertical_margin"
android:paddingLeft="#dimen/table_horizontal_margin"
android:paddingRight="#dimen/table_horizontal_margin"
android:paddingTop="#dimen/table_vertical_margin"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/table_vertical_margin"
android:paddingLeft="#dimen/table_horizontal_margin"
android:paddingRight="#dimen/table_horizontal_margin"
android:paddingTop="#dimen/table_vertical_margin"
>
<TextView
android:id="#+id/textView51"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:linksClickable="true"
android:focusableInTouchMode="true"
android:text="#string/txtPn51" />
<TextView
android:id="#+id/textViewC51"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:linksClickable="true"
android:focusableInTouchMode="true"
android:textSize="15sp"
android:focusable="true"
android:fitsSystemWindows="true"
android:text="#string/txtC51" />
</TableRow>
</LinearLayout>
</TableLayout>
</ScrollView>
</RelativeLayout>
You seem to have two textViews one with
id = textView51
id = textViewC51
in your onCreate you are trying to find the first textview and pass it to another
textViewC51 = (TextView) findViewById(R.id.textView51);
Try to change the previous line with:
textViewC51 = (TextView) findViewById(R.id.textViewC51);
and see if it works for you.
Seems like you are trying to implement something when the user clicks the textview.If this is the case you can just use a spinner, Where you can implement the said functionality without much complexity
you implemented the View.OnClickListener and I'm assuming that you also include in the xml the android:onclick attribute in your xml file?..

Change textview dynamically in Viewflipper

pretty easy question here, but I am not a java superuser quite yet.
I am using a ViewFlipper to provide a number of images, and a sliding-drawer to contain text specific to each image. I would like to have the text of the sliding drawer change to a specific string dependent on which child view is currently displayed.
Here is the XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/previous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Prev" />
<Button
android:id="#+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Next" />
</LinearLayout>
<ViewFlipper
android:id="#+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:id="#+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="#drawable/image1"></ImageView>
<ImageView android:id="#+id/imageView2" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="#drawable/image2"></ImageView>
</ViewFlipper>
</LinearLayout>
here is the java:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
flipper = (ViewFlipper)findViewById(R.id.flipper);
next = (Button) findViewById(R.id.next);
previous = (Button) findViewById(R.id.previous);
imageview1 = (ImageView)findViewById(R.id.imageView1);
imageview2 = (ImageView)findViewById(R.id.imageView2);
next.setOnClickListener(this);
previous.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == next) {
flipper.setInAnimation(inFromRightAnimation());
flipper.setOutAnimation(outToLeftAnimation());
flipper.showNext();
}
if (v == previous) {
flipper.setInAnimation(inFromLeftAnimation());
flipper.setOutAnimation(outToRightAnimation());
flipper.showPrevious();
}
}
I'm sure the answer is really obvious, but that's why I need your help....THANKS!
When you call showNext() and showPrevious(), update your TextView to match.

Categories