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.
Related
So I am just playing around in android and found something really strange. Before I states what is wrong let me give the code.
Here is my Custom Viewgroup code:
package com.ayto.android.cleverpad;
import android.content.Context;
import android.graphics.Color;
import android.graphics.RectF;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
public class noteLayout extends ViewGroup {
float leftOrientationSize = 0;
float rightOrientationSize=0;
public noteLayout(Context activityContext)
{
super(activityContext);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
RelativeLayout mainParent = (RelativeLayout) getParent();
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
child.measure(MeasureSpec.makeMeasureSpec((mainParent.getWidth()/2)-30,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(200,MeasureSpec.AT_MOST));
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int numberOfChild = getChildCount();
for (int i = 0;i<numberOfChild;i++){
View childView = getChildAt(i);
float childHeight = (float) childView.getMeasuredHeight();
float childWidth = (float) childView.getMeasuredWidth();
RectF rect = new RectF();
rect.bottom = childHeight+20;
rect.top = 20;
rect.left = 20;
rect.right = childWidth+20;
childView.layout((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
}
}
}
and here is the xml file that I add (addView()) to CustomView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#android:color/holo_blue_bright">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Title"
android:id="#+id/displayNoteTitle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Test"
android:id="#+id/displayNote"
android:padding="5dp"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:ellipsize="end"
android:layout_above="#+id/displayNoteTitle"
android:layout_alignRight="#+id/displayNoteTitle"
android:layout_alignEnd="#+id/displayNoteTitle" />
</RelativeLayout>
So basically what I did was create an instance of my noteLayout note = new noteLayout(getApplicationContext()) and use the layout inflater to inflate the views from my xml. Then I use noteLayout.addView() to add the inflated view into my custom viewgroup. My problem is that only the textview with the android:Text = "Title" is displayed and the other seem to not render. I am not so sure why this is the case.
ActivityMain
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RelativeLayout;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
noteLayout test = new noteLayout(getApplicationContext());
test.addView(getLayoutInflater().inflate(R.layout.Layout,null));
((RelativeLayout) findViewById(R.id.mainActivity)).addView(test);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Okay. So after our discussion, managed to see what was happening.. I'll explain it thoroughly as it might be confusing.. First of.. In the MainActivity the noteLayout was initialized like so:
noteLayout test = new noteLayout(getApplicationContext());
and is then passed with another RelativeLayout that contains the 2 TextViews :
((RelativeLayout) findViewById(R.id.mainActivity)).addView(test);
So now, the hierarchy would look like this:
RelativeLayout(activity_main)
-- RelativeLayout(one from xml)
---- TextView(title)
---- TextView(body)
And in the code of noteLayout in onMeasured() this line appears:
RelativeLayout mainParent = (RelativeLayout) getParent();
-- which means that the mainParent it gets is the RelativeLayout of the MainActivity (R.layout.activity_main), after that, the loop was made:
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
child.measure(MeasureSpec.makeMeasureSpec((mainParent.getWidth()/2)-30,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(200,MeasureSpec.AT_MOST));
}
To verify this, I put a log inside the loop and it returns only 1 child. So what I did is modify the loop like so:
RelativeLayout mainParent = (RelativeLayout) getParent();
final RelativeLayout child = (RelativeLayout) getChildAt(0);
child.measure(MeasureSpec.makeMeasureSpec((mainParent.getWidth() / 2) - 30, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((mainParent.getHeight() / 2) - 30, MeasureSpec.EXACTLY));
Log.d("SAMPLE", "RelativeLayout Child childcount: " + child.getChildCount());
for (int i = 0; i < child.getChildCount(); i++) {
Log.d("SAMPLE", "In loop: " + i);
final View childOfChild = child.getChildAt(i);
childOfChild.measure(MeasureSpec.makeMeasureSpec((mainParent.getWidth() / 2) - 30, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(200, MeasureSpec.AT_MOST));
}
You can see here that I treated the child of the first RelativeLayout as another RelativeLayout then made the loop using the child.getChildCount(). Also (I just added default measure for the second RelativeLayout, you can edit it to whichever you prefer). This calls the TextViews properly now as to what you would expect from your code.
Here is a screenshot after running the code.
So overall. I just edited out the onMeasure() part of your code.. The main problem was just with which layout you were referring and looping. :D
So i have a simple app, just a menu with a few buttons, when a button is clicked you are brought to a new page. The page has a button, which when clicked, keeps changing its background image until it runs out of images (list of image names stored in strings), then you are brought back to the main menu. I can do this twice, then on the third attempt, if i click a button on the menu the app crashes. This doesnt happen on the emulator, only when i run it on my phone. I dont know why this is happening
package com.example.otapp;
import com.example.otapp.R.raw;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.media.MediaPlayer;
public class MainActivity extends ActionBarActivity {
public static String DPExtension;//Holds the letters dp
public String list;
public static int Screen_Height;//holds screen height
public static int Screen_Width;//holds screen width
public Intent intent;
public MediaPlayer audio;
public final static String EXTRA_MESSAGE = "com.example.otapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//this code block is for getting the screen proportions
Display getdisplay = getWindowManager().getDefaultDisplay();
DisplayMetrics dispMetrics = new DisplayMetrics();
getdisplay.getMetrics(dispMetrics);
float densitydp = getResources().getDisplayMetrics().density;
float ScreenHeightdp = dispMetrics.heightPixels / densitydp;
float ScreenWidthdp = dispMetrics.widthPixels / densitydp;
//Below dimension value holders do not use pixel density
float ScreenHeightCheck = dispMetrics.heightPixels;
float ScreenWidthCheck = dispMetrics.heightPixels;
DPExtension = "dp";
Screen_Height = (int) ScreenHeightCheck;
Screen_Width = (int) ScreenWidthCheck;
//The printlns are so I can discern the outputs in LogCat
//System.out.println("Screen Height:" + Screen_Height);
//System.out.println("Screen Width:" + Screen_Width);
View Button1 = findViewById(R.id.Button01);
LinearLayout.LayoutParams params = (LayoutParams) Button1.getLayoutParams();
params.height = Screen_Height/3;
Button1.setLayoutParams(params);
View Button2 = findViewById(R.id.Button02);
Button2.setLayoutParams(params);
View Button3 = findViewById(R.id.Button03);
Button3.setLayoutParams(params);
View Button4 = findViewById(R.id.Button04);
Button4.setLayoutParams(params);
Button1.setOnClickListener(onClickListener);
Button2.setOnClickListener(onClickListener);
Button3.setOnClickListener(onClickListener);
Button4.setOnClickListener(onClickListener);
Button1.setBackgroundResource(getResources().getIdentifier("gettingup", "drawable", getPackageName()));
intent = new Intent(this, DisplayMessageActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
audio = MediaPlayer.create(MainActivity.this, raw.buttonsound);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private OnClickListener onClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
// play sound
audio.start();
// do different things for each different button
switch(v.getId()) {
case R.id.Button01:
list = "Get Up";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
case R.id.Button02:
list = "Get Dressed";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
case R.id.Button03:
list = "Get Dressed";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
case R.id.Button04:
list = "Get Dressed";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
}
}
};
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent" android:background="#1E90FF">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/Button01"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button_send"/>
<Button
android:id="#+id/Button03"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button2_send" />
<Button
android:id="#+id/Button04"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button3_send" />
<Button
android:id="#+id/Button02"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button4_send" />
</LinearLayout>
</ScrollView>
If the source above is formatted correctly, line 99, which is where the NullPointerException is thrown, is:
audio.start();
This means that audio is null. It is declared on line 83:
audio = MediaPlayer.create(MainActivity.this, raw.buttonsound);
Most likely what's happening is that the MediaPlayer.create is unable to located the raw.buttonsound. I'd debug at this line and verify that the MediaPlayer is failing to create the audio.
Try moving the definition of the onClickListener object into the onCreate method.
You can declare it as a member variable, but you should create the object and assign it to the field in onCreate()
I'm new in android programming and I'm making a very simple app.
I only have one text view and one button, and when I click the button I want to show in the text view a value that represents how long the activity was open.
this is my xml file:
<Button
android:id = "#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Button" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/button"
android:layout_centerHorizontal="true"
android:text=" " />
</RelativeLayout>
and this is my java file:
package com.diogoc.teste;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textView;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(Listener);
}
#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;
}
private OnClickListener Listener = new OnClickListener() {
public void onClick(View v) {
//It's here
textView.setText("You take");
}
};
}
Thank you.
Add this member variable to the class:
long startTime;
Add this to your onCreate()-method:
startTime = System.currentTimeMillis();
Add this to your onClick()-method:
long timeElapsedMS = System.currentTimeMillis()-startTime; //gets the time difference in milliseconds
long timeElapsedSeconds = timeElapsedMS/1000;
textView.setText("You took "+timeElapsedSeconds+" seconds");
Something like this in your onCreate will work:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Other stuff omitted */
final long start= System.currentTimeMillis();
final Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run(){
textView.setText(System.currentTimeMillis() - start);
handler.postDelayed(this, 100);
}
}, 100);
}
The code in the run() method will run indefinately every 100 ms, updating the text in your textview with the milliseconds passed since the call to onCreate().
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 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:
....