I am current working through a SeekBar example located here. This example has one seek bar, but I wanted to see what would happen if I added two more seek bars.
While the listeners all seem to still work, I want to add the name of the SeekBar to the toast that shows up while tracking the the touch bar. However, I can't just add the name of the variable to the toast ( the passed in seekBar is a widget ) and this doesn't fit the function call of toString().
How would I add the name of the seekBar that I'm focusing on to the Toast?
MainActivity.java:
package com.javatpoint.seekbar;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnSeekBarChangeListener{
SeekBar seekBar1, seekBar2, seekBar3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar1=(SeekBar)findViewById(R.id.seekBar1);
seekBar1.setOnSeekBarChangeListener(this);
seekBar2=(SeekBar)findViewById(R.id.seekBar2);
seekBar2.setOnSeekBarChangeListener(this);
seekBar3=(SeekBar)findViewById(R.id.seekBar3);
seekBar3.setOnSeekBarChangeListener(this);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
//This is where I want to print out the variable name
Toast.makeText(getApplicationContext(), "seekbar progress: "+progress, Toast.LENGTH_SHORT).show();
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
Toast.makeText(getApplicationContext(),seekBar +"seekbar touch started!", Toast.LENGTH_SHORT).show();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(getApplicationContext(),"seekbar touch stopped!", Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
activity_main.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: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=".MainActivity" >
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="120dp" />
<SeekBar
android:id="#+id/seekBar2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_below="#id/seekBar1"/>
<SeekBar
android:id="#+id/seekBar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_below="#id/seekBar2"/>
Someone posted a link to this post last night detailing the use of tags to solve my problem, but unfortunately they either removed their post or it was deleted before I could mark it as the correct answer.
I was able to use the info in that post to set a string as the tag for each seekBar, and then pass that into a new function that took the tag as well as the progress from the seekbar to show different toasts for each seekbar.
Here was the final version of the MainActivity
package com.javatpoint.seekbar;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnSeekBarChangeListener{
SeekBar seekBar1, seekBar2, seekBar3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar1=(SeekBar)findViewById(R.id.seekBar1);
seekBar1.setOnSeekBarChangeListener(this);
seekBar1.setTag("1");
seekBar2=(SeekBar)findViewById(R.id.seekBar2);
seekBar2.setOnSeekBarChangeListener(this);
seekBar2.setTag("2");
seekBar3=(SeekBar)findViewById(R.id.seekBar3);
seekBar3.setOnSeekBarChangeListener(this);
seekBar3.setTag("3");
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
changeValue(seekBar.getTag(), progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
Toast.makeText(getApplicationContext(),"seekbar touch started!", Toast.LENGTH_SHORT).show();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(getApplicationContext(),"seekbar touch stopped!", Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void changeValue(Object a, int progress){
if(a=="1"){
Toast.makeText(getApplicationContext(), "seekbar1 progress: "+progress, Toast.LENGTH_SHORT).show();
}
if(a=="2"){
Toast.makeText(getApplicationContext(), "seekbar2 progress: "+progress, Toast.LENGTH_SHORT).show();
}
if(a=="3"){
Toast.makeText(getApplicationContext(), "seekbar3 progress: "+progress, Toast.LENGTH_SHORT).show();
}
}
}
Related
I know this question was asked and somewhat answered before, but none of the solutions I found so far really worked out for me: I have a custom seekBar with a large square block for the thumb, which I draw on the fly, and I want the seekBar progress to change only when the thumb is being dragged.
Large thumb seekBar
I looked around and tried out all of the proposed solutions I could find, and some worked better then others, but they all have a big issue (for me at least): if I detect the boundaries of the thumb in order to start dragging the thumb, the onTouch ACTION_DOWN event makes the thumb jump to whatever position the pointer is on the screen, within the thumb's boundaries, of course.
If the thumb size is small, this is almost a non issue, but on a large thumb, this behavior is really annoying.
To make matters worse, if I declare a thumb offset of 0 to keep the thumb inside the seekBar, the jumping behavior changes with respect to where on the seekbar the thumb is: indetermined jump direction right in the middle of the seekbar, or it jumps to the right if the thumb is on the left half of the seekbar, or to the left if the thumb is on the right half of the seekbar.
Here's my starting code, I removed all of my failed attempts to make the seekBar's thumb move only when a drag starts:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/progressText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mySeekbar"
app:layout_constraintVertical_bias="0.154" />
<com.example.thumbonlyseekbar.MySeekBar
android:id="#+id/mySeekbar"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="20dp"
android:layout_marginTop="150dp"
android:layout_marginEnd="20dp"
android:indeterminate="false"
android:max="99"
android:progress="0"
android:progressDrawable="#drawable/my_seekbar"
android:thumb="#drawable/thumb"
android:thumbOffset="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MySeekbar.java
package com.example.thumbonlyseekbar;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
public class MySeekBar extends androidx.appcompat.widget.AppCompatSeekBar {
Drawable mThumb;
public MySeekBar(#NonNull Context context) {
super(context);
}
public MySeekBar(#NonNull Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySeekBar(#NonNull Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setThumb(Drawable thumb) {
super.setThumb(thumb);
mThumb = thumb;
}
public Drawable getSeekBarThumb() {
return mThumb;
}
}
MainActivity.java
package com.example.thumbonlyseekbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
MySeekBar customSeekBar;
TextView progressValueText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customSeekBar = findViewById(R.id.mySeekbar);
progressValueText = findViewById(R.id.progressText);
progressValueText.setText(String.valueOf(customSeekBar.getProgress()));
customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValueText.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
thumb.xml
package com.example.thumbonlyseekbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
MySeekBar customSeekBar;
TextView progressValueText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customSeekBar = findViewById(R.id.mySeekbar);
progressValueText = findViewById(R.id.progressText);
progressValueText.setText(String.valueOf(customSeekBar.getProgress()));
customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValueText.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
my_seekbar.xml
package com.example.thumbonlyseekbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
MySeekBar customSeekBar;
TextView progressValueText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customSeekBar = findViewById(R.id.mySeekbar);
progressValueText = findViewById(R.id.progressText);
progressValueText.setText(String.valueOf(customSeekBar.getProgress()));
customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValueText.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
If you would like to see an example of what I mean by a no-thumb-jump seekBar, please take a look at the AMPLIFi Remote app in Google Play Store (it may only work on older devices, it works on my OREO 8.1, you may need to try it in an emulator that allows downloads from Google Play if you don't have an older device). The thumb's progress is unbelievably smooth, and there's absolutely no jumping around. Whoever wrote that app did an awesome job!
Many, many thanks, any suggestion is much appreciated!
My Main Activity has a background music, and I want to stop it whenever I can, through a checkbox. I have the codes already in order to set the background music into the Main activity, and it works perfect. The problem is that I want to stop a specific song from another activity using a CheckBox. I configured the checkbox, however, it does not work. Somehelp is really appreciated.
PD: The comunication between these two activities work well. It is the checkbox that does not work
Here are my codes used.
MainActivity.java
`
public class MainActivity extends Activity implements View.OnClickListener {
MediaPlayer bkgrdmsc;
private int lmusic_checked = SettingsActivity.music_checked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (lmusic_checked == 0){
bkgrdmsc = MediaPlayer.create(MainActivity.this, R.raw.backgroundmusic);
bkgrdmsc.setLooping(true);
bkgrdmsc.start();
}
#Override
protected void onPause() {
if (lmusic_checked == 0){
bkgrdmsc.release();
}
SettingsActivity.music_checked =0;
super.onPause();
bkgrdmsc.release();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//inflate the menu; this adds items to the action bar if this is present
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent s_intent = new Intent(this, SettingsActivity.class);
startActivity(s_intent);
return true;
}
else if (id == R.id.logo_home){
Intent t_intent = new Intent(this, Twitter.class);
startActivity(t_intent);
return true;
}
return super.onOptionsItemSelected(item);
}
activity_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="271dp"
android:layout_height="77dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/c_general"
android:id="#+id/textView"
android:layout_gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="57dp"
android:textSize="26dp" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/turn_on_music"
android:id="#+id/CheckBox"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true"
android:checked="false"
android:singleLine="false"
android:textColor="#000000" />
</RelativeLayout>
SettingsActivity.java
package com.example.json.publicomidas;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.CompoundButton;
public class SettingsActivity extends Activity {
public static int music_checked= 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_settings);
music_off();
}
public void music_off(){
CheckBox checkBox1 = (CheckBox) findViewById(R.id.CheckBox);
checkBox1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.isChecked()) {
music_checked = 1;
} else {
music_checked = 0;
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//inflate the menu; this adds items to the action bar if this is present
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_settings, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.home) {
Intent s_intent = new Intent(this, MainActivity.class);
startActivity(s_intent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Man, you should not do it this way... You cannot make two activities communicate each other with a static field :) When you change the value of music_checked in SetttingsActivity this changes nothing in the MainActivity.
My advice is to create a Service that runs the music. Both the activities should properly bind to the service and manipulate the music playback.
Update1
The communication you have implemented using this static field works only in one direction. You cannot stop the music by changing the music_checked property. It is a property of the SettingsActivity class and the MainActivity instance knows nothing about its state.
The proper way to implement this is using a Service that plays the music. It is not correct to play the music from an Activity if you want the playback to continue after the activity is paused/stoped. Create a bound service and bind each activity to the service in their onResume or onStart method (and unbind in onPause/onStop). By binding to the service you receive an object that exposes some API (you have to define this API and create the object according to the functionality you want to have). Using this API you can control the service from both the activities.
I'll advise you to read a bit more about activities and services in android and their lifecycle.
i have checked everything in this but still i am getting a null pointer exception . whenever i am trying to change the properties of button in java file, app stop working and logcat showing null pointer exception. plzz help me out
here is my code
package com.example.rapid_finger;
import java.util.Random;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
public class PlayScreen extends Activity {
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Random rand = new Random();
int data = rand.nextInt(99);
String str = Integer.toString(data);
Button b = (Button) findViewById(R.id.b1);
b.setText(str);
setContentView(R.layout.activity_play_screen);
// Show the Up button in the action bar.
setupActionBar();
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.play_screen, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up- vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
and here is my xml file
<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: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=".PlayScreen" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/scores" />
<Button
android:id="#+id/b1"
android:background="#drawable/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
You did findViewById before you setContentView.
setContentView should come first
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_screen);
Random rand = new Random();
int data = rand.nextInt(99);
String str = Integer.toString(data);
Button b = (Button) findViewById(R.id.b1);
b.setText(str);
// Show the Up button in the action bar.
setupActionBar();
}
put setContentView(R.layout.activity_play_screen); after super.onCreate(savedInstanceState);
// replace this code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_screen);
Random rand = new Random();
int data = rand.nextInt(99);
String str = Integer.toString(data);
Button b = (Button) findViewById(R.id.b1);
b.setText(str);
// Show the Up button in the action bar.
setupActionBar();
}
I have a basic android app set up with a scroll view and text added to it dynamically.
I want it to scroll to the bottom when text is added (which already happens) but I only want it to scroll to the bottom if you are already at the bottom, so if you're reading something it doesn't just scroll.
Here's what I have so far.
private void AddText(final String msg){
this.runOnUiThread(new Runnable() {
public void run() {
TextView log = (TextView) findViewById(R.id.chatlog);
if(log.getText().equals("Loading...")){
log.setText(msg);
}else{
ScrollView scroller = (ScrollView) findViewById(R.id.scroll_container);
//set current scroll position
int scroll_pos = scroller.getScrollY();
//scroll to bottom
scroller.fullScroll(ScrollView.FOCUS_DOWN);
//set bottom position
int scroll_bot = scroller.getScrollY();
//add the text
log.append("\r\n" + msg);
//if you weren't at the bottom
//scroll back to where you were.
//This isn't working, scroll bot is the same
//as scroll pos.
if(scroll_pos != scroll_bot){
scroller.scrollTo(0, scroll_pos);
}
//System.out.println("Pos: " + scroll_pos);
//System.out.println("Bot: " + scroll_bot);
}
}
});
}
The best solution I found so far is to use scrollView.post() method with a runnable that will be invoked after text change:
final ScrollView scrollView = (ScrollView) findViewById(R.id.consoleTab);
TextView textView = (TextView) findViewById(R.id.consoleView);
boolean autoScroll = (textView.getBottom() - (scrollView.getHeight() + scrollView.getScrollY())) <= 0;
textView.setText(state.getConsole().getText());
if (autoScroll) {
scrollView.post(new Runnable() {
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
Here is a working example I got running in the emulator and on my galaxy s.
Basically there are two buttons to add text to the bottom text view, depending on your devices size only the second of these should be usable to see the autoscrolling. The textview being edited uses the ontextchangedlistener to check the scroll position before its text is changed and then to call a delayed (so the screen can update with the additional text) autoscroll where appropriate, after the text has changed.
The layout xml is as follows:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollmain">
<RelativeLayout
android:id="#+id/mainRelative"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to the scrolling test application!" />
<Button
android:id="#+id/firstTextAddButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/titleText"
android:text="Click me to add text to the textview below without scrolling"/>
<Button
android:id="#+id/secondTextAddButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/firstTextAddButton"
android:layout_marginTop="380dp"
android:text="Click me to add text to the textview below and scroll (if you are currently scrolled all the way to the bottom)"/>
<TextView
android:id="#+id/textToEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/secondTextAddButton"
android:textSize="18sp"
android:text="Some text to get us started."/>
/>
</RelativeLayout>
</ScrollView>
And the code for the activity is as follows:
package code.example.scrollingontextchange;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
public class MainActivity extends Activity {
private int scroll_pos;
private int maxScrollPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.textToEdit);
tv.addTextChangedListener(new TextWatcher(){
#Override
public void afterTextChanged(Editable s) {
if(scroll_pos == maxScrollPosition)
{
Handler h = new android.os.Handler()
{
#Override
public void handleMessage(android.os.Message msg)
{
switch(msg.what)
{
case 0 :
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ScrollView scrll = (ScrollView)findViewById(R.id.scrollmain);
scrll.fullScroll(ScrollView.FOCUS_DOWN);
break;
default :
break;
}
}
};
h.sendEmptyMessage(0);
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
ScrollView scrll = (ScrollView)findViewById(R.id.scrollmain);
RelativeLayout rl = (RelativeLayout)findViewById(R.id.mainRelative);
scroll_pos = scrll.getScrollY();
maxScrollPosition = rl.getHeight() - scrll.getHeight();
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
});
OnClickListener addTextOnClick = new OnClickListener() {
#Override
public void onClick(View v) {
TextView tv = (TextView)findViewById(R.id.textToEdit);
tv.setText(tv.getText() + "\nA long time ago, in a galaxy s far far away............");
}
};
Button b = (Button)findViewById(R.id.firstTextAddButton);
b.setOnClickListener(addTextOnClick);
Button b2 = (Button)findViewById(R.id.secondTextAddButton);
b2.setOnClickListener(addTextOnClick);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Hope this helps.
Don't ask me why, but setting your TextView's gravity to bottom it does exactly what you want.
I use example from http://startandroid.ru/uroki/vse-uroki-spiskom/128-urok-67-dialogi-progressdialog.html
We have two buttons.
onClick first button - show some progress dialog.
onClick second button - show some progress dialog.
If I click fast on first button after that on second button then it is showing two progress dialogs. How to disable this posibility?(Is it good to disable this two buttons when is clicked one of them, or disable LinearLayout, ...)
strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dflt">Обычный</string>
<string name="horiz">Горизонтальный</string>
<string name="app_name">ProgressDialog</string>
</resources>
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"
android:orientation="vertical">
<Button
android:id="#+id/btnDefault"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/dflt"
android:onClick="onclick">
</Button>
<Button
android:id="#+id/btnHoriz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/horiz"
android:onClick="onclick">
</Button>
</LinearLayout>
MainActivity.java:
package ru.startandroid.develop.p0671progressdialog;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
public class MainActivity extends Activity {
ProgressDialog pd;
Handler h;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onclick(View v) {
switch (v.getId()) {
case R.id.btnDefault:
pd = new ProgressDialog(this);
pd.setTitle("Title");
pd.setMessage("Message");
// добавляем кнопку
pd.setButton(Dialog.BUTTON_POSITIVE, "OK", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
pd.show();
break;
case R.id.btnHoriz:
pd = new ProgressDialog(this);
pd.setTitle("Title");
pd.setMessage("Message");
// меняем стиль на индикатор
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// устанавливаем максимум
pd.setMax(2148);
// включаем анимацию ожидания
pd.setIndeterminate(true);
pd.show();
h = new Handler() {
public void handleMessage(Message msg) {
// выключаем анимацию ожидания
pd.setIndeterminate(false);
if (pd.getProgress() < pd.getMax()) {
// увеличиваем значения индикаторов
pd.incrementProgressBy(50);
pd.incrementSecondaryProgressBy(75);
h.sendEmptyMessageDelayed(0, 100);
} else {
pd.dismiss();
}
}
};
h.sendEmptyMessageDelayed(0, 2000);
break;
default:
break;
}
}
}
Instead of disabling views just create a boolean variable that you set to true when a dialog is clicked. In your onClick function you can check if there is already an active dialog. Then you can add an onDismissListener to your dialogs and reset the boolean variable.
Are you saying when clicking another button, you want the current progress dialog to go away before showing the new one? I think you would need to dismiss the dialog if it is showing then with a simple check in your onClick()
public void onclick(View v) {
if (pd != null) {
pd.dismiss();
}
switch (v.getId()) {
case R.id.btnDefault:
....