У меня есть странная проблема, которая возникает в 1.6, 2.2 и MyTouch 3G Slide (это API # 7, и в списке «Выбор устройств Android» указано «2.1-Update1»).Если кто-то может объяснить, что я делаю неправильно и как это исправить (или, возможно, подтвердить, что это ошибка Android), я был бы очень признателен!
Основная идея для моего приложения - сделатьсекундомер - что-то вроде того, что пользователь может нажать кнопку, чтобы запустить таймер, а затем снова нажать ее, чтобы остановить (приостановить) таймер;дальнейшие нажатия чередуются между возобновлением таймера и его приостановкой.
У меня есть ScrollView верхнего уровня, который содержит RelativelLayout, который содержит несколько виджетов.Первый виджет - ОГРОМНАЯ кнопка (чтобы ее было легко нажимать), которая толкает все остальные мои виджеты ниже нижней части экрана.Это сделано намеренно, так как я хочу положиться на ScrollView (и экранное напоминание для пользователя), чтобы сделать остальные параметры ввода доступными.
У меня есть простая настройка типа конечного автоматагде mState - текущий режим (STATE_TIMER_NOT_STARTED до того, как пользователь нажимает какие-либо кнопки, ... RUNNING после первого нажатия, а затем ... PAUSED после второго, возврат в ... RUNNING после третьего и т. д. и т. д.).
Все это прекрасно работает, за исключением того, что, когда таймер работает, и пользователь снова нажимает кнопку пуска / остановки / возобновления, ScrollView будет прокручиваться вниз.Я НЕ запускаю эту команду (у меня даже нет ссылки на объект ScrollView), и я не уверен, почему он это делает.
REPRO: Компилировать + запустить приведенные ниже примеры.Когда приложение запустится, нажмите кнопку «Start Timing».Используйте большой палец (или мышь) для перетаскивания экрана вверх (чтобы вы могли увидеть панель оценок), затем перетащите его вниз (чтобы кнопка снова полностью появилась на экране).Нажмите кнопку (которая теперь читает «PauseTiming») еще раз, и она немного подпрыгнет.Он НЕ должен прыгать / прокручиваться вниз, так как нет оператора (который я вижу), который говорит ему прокручивать вниз.Насколько я могу судить, именно setText вызывает прокрутку (когда я закомментирую эти строки, прокрутка не происходит).
ЧТО Я ЗАПРОСУ: Если я делаю что-то глупое, и вы могли быукажите, что это такое, я бы очень признателен!:) *** Интересно, может ли «сенсорный режим» как-то иметь к этому отношение, поскольку это не происходит (в эмуляторе), когда я использую колесо прокрутки мыши для перемещения панели вверх (т. Е. Вместосимуляция перетаскивания пальцев).Я не могу найти много всего в сенсорном режиме, и ничего особенного в фокусировке / выборе в сенсорном режиме в ScrollView
Если вы можете подтвердить, что эта ошибка возникает и для вас, это тоже будет хорошо(поскольку несчастье любит компанию. AHEM Я имею в виду, поскольку это может помочь подтвердить, что это не только я :)).
MyTestApp.java
package bug.android.scrollview;
import android.app.Activity;
import android.os.Bundle;
import android.text.format.Time;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
public class MyTestApp extends Activity {
public final static int STATE_TIMER_NOT_STARTED = 1;
public final static int STATE_TIMER_RUNNING = 2;
public final static int STATE_TIMER_PAUSED = 3;
private int mState;
Time t = new Time();
private Time data = new Time();
private Button btnStartStopResume;
private TextView lblSpacer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_time_entry);
btnStartStopResume = (Button) findViewById(R.id.btnStartStopResume);
// Set the button's size so that the other info will also be visible
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE))
.getDefaultDisplay();
// This is such a hack, but the windowScroller doesn't appear to
// have a height at this point in the lifecycle (nor in 'onResume' :( )
btnStartStopResume.setHeight(display.getHeight() - 200);
lblSpacer = (TextView) findViewById(R.id.lblSpacer);
reset();
}
public void doStartStopResume(View v) {
if (mState == MyTestApp.STATE_TIMER_NOT_STARTED) {
mState = MyTestApp.STATE_TIMER_RUNNING;
data.setToNow();
} else if (mState == MyTestApp.STATE_TIMER_RUNNING) {
mState = MyTestApp.STATE_TIMER_PAUSED;
String s = getString(R.string.add_scroll_down_to_add);
lblSpacer.setText(s);
} else if (mState == MyTestApp.STATE_TIMER_PAUSED) {
mState = MyTestApp.STATE_TIMER_RUNNING;
}
}
public void doReset(View v) {
}
public void doNewRunClick(View v) {
}
public void doAddTiming(View v) {
}
public void reset() {
mState = STATE_TIMER_NOT_STARTED;
}
}
new_time_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/windowScroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/btnStartStopResume"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:text="Start Timing"
android:textSize="40dp"
android:height="290dp"
android:onClick="doStartStopResume" />
<TextView
android:id="@+id/lblSpacer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btnStartStopResume"
android:layout_centerHorizontal="true"
android:text="@string/add_scroll_down_for_more" />
<TextView
android:id="@+id/lblTimeStartLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/lblSpacer"
android:layout_alignParentLeft="true"
android:clickable="true"
android:onClick="adjustStartTime"
android:text="Start of this run:"
android:textSize="8dp" />
<TextView
android:id="@+id/lblTimeStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lblTimeStartLabel"
android:layout_alignParentLeft="true"
android:clickable="true"
android:onClick="adjustStartTime"
android:text="--:--:-- --"
android:textColor="#FFFFFF"
android:textSize="26dp" />
<TextView
android:id="@+id/lblElapsedLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lblSpacer"
android:layout_alignRight="@id/lblSpacer"
android:layout_marginRight="5dp"
android:text="Elapsed Time:"
android:textSize="8dp" />
<TextView
android:id="@+id/lblTimeElapsed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lblElapsedLabel"
android:layout_alignRight="@id/lblSpacer"
android:layout_marginRight="5dp"
android:textColor="#99ff66"
android:text="-- m -- sec"
android:textSize="26dp"
android:layout_marginBottom="10dip"/>
<CheckBox
android:id="@+id/chkNewRun"
android:onClick="doNewRunClick"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/lblTimeElapsed"
android:text="This is a new run of timings"
android:layout_marginBottom="10dip" />
<TextView
android:id="@+id/lblIntensity"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Intensity (1 = none 5 = max)"
android:layout_below="@id/chkNewRun" />
<RatingBar
android:id="@+id/rbIntensity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lblIntensity"
android:numStars="5"
android:rating="2"
android:layout_marginBottom="5dip" />
<TextView
android:id="@+id/lblNotes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Notes:"
android:layout_below="@id/rbIntensity" />
<EditText
android:id="@+id/txtNotes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background"
android:layout_below="@id/lblNotes"
android:layout_marginBottom="10dip" />
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/txtNotes"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:text="Reset"
android:onClick="doReset" />
<Button
android:id="@+id/btnOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/txtNotes"
android:layout_toRightOf="@id/btnReset"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:text="Add Timing To List"
android:onClick="doAddTiming" />
</RelativeLayout>
</ScrollView>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Timer</string>
<string name="dlg_edit_timing_title">Edit A Timing</string>
<string name="add_scroll_down_for_more">< Scroll down for more options! ></string>
<string name="add_scroll_down_to_add">< Scroll down to save this timing! ></string>
<string name="start_timing">Start Timing\n\n</string>
<string name="stop_timing">Pause Timing\n\n</string>
<string name="resume_timing">Resume Timing\n\n</string>
</resources>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="bug.android.scrollview"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MyTestApp"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="5" />
</manifest>
ОБНОВЛЕНИЕ 1: добавление
if( btnStartStopResume.isInTouchMode() )
Toast.makeText(this, "TOUCH MODE", 2000);
else
Toast.makeText(this, "NOT touch mode", 2000);
, а затем установка точек останова в отладчике подтверждает, что кнопка всегда находится в сенсорном режиме (независимо от того, перетаскиваю ли я панель вверх / вниз,или колесико мыши вверх / вниз).Таким образом, это сочетание того, что вы находитесь в сенсорном режиме и перетаскиваете панель пальцем после 2-го нажатия кнопки (т. Е. Когда приложение находится в режиме «остановка / пауза»), что вызывает странное дополнительное время в последующих паузах.
ОБНОВЛЕНИЕ 2: Я только что заметил, что он прокручивается до EditText, и не дальше.Похоже, что когда вы перемещаете панель вниз, EditText получает выделение, а после события щелчка ScrollView прокручивает обратно к объекту, у которого есть выделение.Кажется, объясняет, почему подход с колесом мыши не имеет этой проблемы (он перемещает выделение / фокус обратно на кнопку).