2010-06-24 66 views
4

我有1.6,2.2和MyTouch 3G幻燈片(這是API#7,在Android設備選配器中列爲「2.1-Update1」)發生這個奇怪的問題。如果任何人可以解釋我在做什麼錯誤&如何解決它(或者可能確認這是一個Android錯誤),我將不勝感激!爲什麼TextView.setText會導致封閉的ScrollView滾動?

我的應用程序的基本思路是製作一個秒錶類的東西,用戶可以點擊一個按鈕來啓動一個計時器,然後再次點擊它來停止(暫停)計時器;進一步點擊恢復定時器和暫停定時器之間交替。

我有一個頂級ScrollView,其中包含一個RelativelLayout,其中包含一些小部件。第一個小部件是一個巨大的按鈕(這樣很容易按下),它將我所有其他小部件推到屏幕底部以下。這是故意的,因爲我想依靠ScrollView(以及屏幕提示給用戶)使其餘的輸入選項可用。

我有一個簡單的狀態機類型設置,其中mState是當前模式(STATE_TIMER_NOT_STARTED在用戶按任何按鈕之前,......在第一次按下之後運行,然後......在第二次之後,回到......第三等後跑步等)。

所有這些都很好,除了當計時器正在運行,並且用戶再次按下開始/停止/繼續按鈕時,ScrollView將向下滾動一些方式。我不發佈這個命令(我甚至沒有對ScrollView對象的引用),我不知道它爲什麼這樣做。

REPRO: 編譯+運行以下示例。當應用程序啓動時,按下'Start Timing'按鈕。使用拇指(或鼠標)向上拖動屏幕(以便您可以看到RatingBar),然後將其向下拖動(使按鈕再次完全顯示在屏幕上)。再次點擊按鈕(現在讀取'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">&lt; Scroll down for more options! &gt;</string> 
    <string name="add_scroll_down_to_add">&lt; Scroll down to save this timing! &gt;</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> 

的droidManifest。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> 

UPDATE 1:在調試器添加

 if( btnStartStopResume.isInTouchMode()) 
      Toast.makeText(this, "TOUCH MODE", 2000); 
     else 
      Toast.makeText(this, "NOT touch mode", 2000); 

然後設置斷點確認該鍵總是處於觸摸模式(無論是否我手指拖動面板的上/下,或者將鼠標滾輪向上/向下)。因此,在第二次按下按鈕後(即當應用程序處於「停止/暫停時間」模式)時,處於觸摸模式和手指拖動面板的組合會導致在後續暫停中出現奇怪的額外時序。

更新2: 我剛剛注意到它正在向下滾動到EditText,沒有更多。它看起來像當您將面板向下移動時,EditText將獲取選擇內容,並且在單擊事件之後,ScrollView會滾動回到所選內容。似乎解釋了爲什麼鼠標滾輪方法沒有這個問題(它將選擇/焦點移回到按鈕)。

+0

http://stackoverflow.com/questions/5375838/scrollview-disable-focus-move/7114179#7114179 – yanchenko 2013-05-22 09:41:08

回答

3

舊的線程,但我想我會添加這個以防萬一像周圍一樣搜索。我有同樣的問題,但只是清除焦點沒有幫助。這是最終解決它對我來說:

editText.clearFocus(); 
editText.setTextKeepState(text); 

希望這可以幫助別人。 TextView docs

2

好吧,我有什麼回事手柄,足夠的如何解決它,我認爲我也可以張貼此在這裏,作爲一個答案的想法:

如果調用clearFocus在調用setText之前在EditText上(這是按鈕事件處理程序,以及我通過線程的Handler在這個程序的'真實'版本中運行的幾個定時器),然後一切都按我期望的方式工作(沒有奇怪的自動滾動)。

如果你想使用這個解決方案,你需要清除焦點,以便獲得關注的任何事情,但是,這使得它成爲一個蹩腳的解決方案 - 我會盡力繼續關注這個。在ScrollView文檔中,有一個名爲onRequestFocusInDescendants的方法,其中有一個神祕的註釋:「當在滾動視圖的兒童中尋找焦點時,需要小心一些,不要將焦點放在屏幕上滾動的東西上,這比默認的ViewGroup實現,否則這種行爲可能已經成爲默認設置。「這可能指向這裏發生了什麼......

+0

謝謝,我剛剛遇到了這個問題,並通過清除焦點來解決問題,這在我的情況下是可以的 - 感謝您發佈自己問題的答案。 – 2012-08-19 22:34:36

0

我在這個頁面上試過解決方案,他們沒有爲我工作。每當我點擊視圖中的刷新按鈕時,我都會滾動滾動視圖。我最終做的是在按鈕左側設置一個標題,並將該項目設置爲我的按鈕回調中的焦點。

部分我在我的片段onCreateView的:

final View view = inflater.inflate(R.layout.fragment_diagnostic, container, false); 
view.findViewById(R.id.button_refresh_bluetooth_device).setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     updateBluetoothDevice(); 
     view.findViewById(R.id.bluetooth_device_title).requestFocus(); 
    } 
}); 
view.findViewById(R.id.button_refresh_network).setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     updateNetworkSection(); 
     view.findViewById(R.id.android_network_title).requestFocus(); 
    } 
}); 

我佈局的簡化版本:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/parentPanel" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:paddingTop="@dimen/alert_dialog_padding_material" 
    android:orientation="vertical"> 

    <RelativeLayout 
     android:id="@+id/topPanel" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:clipToPadding="false" 
     android:paddingLeft="@dimen/alert_dialog_padding_material" 
     android:paddingRight="@dimen/alert_dialog_padding_material" 
     android:paddingBottom="@dimen/floating_action_button_margin"> 

     <android.support.design.widget.FloatingActionButton 
      android:id="@+id/button_refresh" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="bottom|end" 
      android:layout_alignParentRight="true" 
      android:padding="@dimen/floating_action_button_margin" 
      android:src="@drawable/ic_fab_refresh" 
      android:contentDescription="@string/content_description_refresh" 
      app:elevation="4dp" 
      app:borderWidth="0dp" 
      app:fabSize="mini"/> 

     <TextView 
      android:id="@+id/alertTitle" 
      style="?android:attr/windowTitleStyle" 
      android:singleLine="true" 
      android:ellipsize="end" 
      android:layout_toLeftOf="@id/button_refresh" 
      android:layout_alignParentLeft="true" 
      android:layout_centerVertical="true" 
      android:paddingBottom="@dimen/floating_action_button_margin" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/title_diagnostics"/> 
    </RelativeLayout> 

    <ScrollView 
     android:id="@+id/scrollView" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:clipChildren="false" 
     android:clipToPadding="false" 
     android:layout_weight="1" 
     android:orientation="vertical" 
     android:minHeight="48dp" 
     android:paddingLeft="@dimen/alert_dialog_padding_material" 
     android:paddingRight="@dimen/alert_dialog_padding_material" 
     android:paddingBottom="@dimen/alert_dialog_padding_material"> 

     <TableLayout 
      android:layout_height="wrap_content" 
      android:layout_width="wrap_content" 
      android:clipChildren="false" 
      android:shrinkColumns="1" 
      android:stretchColumns="1,2"> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:gravity="center_vertical"> 

       <TextView 
        android:id="@+id/bluetooth_device_title" 
        android:layout_width="0dp" 
        android:layout_height="wrap_content" 
        android:layout_weight="1" 
        android:textAppearance="?android:attr/textAppearanceLarge" 
        android:text="@string/title_bluetooth_device" 
        android:focusable="true" 
        android:focusableInTouchMode="true"/> 

       <android.support.design.widget.FloatingActionButton 
        android:id="@+id/button_refresh_bluetooth_device" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="@dimen/floating_action_button_margin" 
        android:src="@drawable/ic_fab_refresh" 
        android:contentDescription="@string/content_description_refresh" 
        app:elevation="4dp" 
        app:borderWidth="0dp" 
        app:fabSize="mini"/> 
      </LinearLayout> 

      <TableRow> 

       <ImageView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginRight="5dp" 
        android:layout_gravity="center_vertical" 
        android:id="@+id/bt_connection_status_image" 
        tools:src="@drawable/ic_check" 
        android:contentDescription="@string/content_description_diagnostic_status"/> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_gravity="center_vertical" 
        android:text="@string/label_state"/> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginLeft="5dp" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_gravity="center_vertical" 
        tools:text="Connected" 
        android:id="@+id/bt_connection_status"/> 

      </TableRow> 

      <LinearLayout 
       android:id="@+id/android_network_title" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:gravity="center_vertical"> 

       <TextView 
        android:layout_width="0dp" 
        android:layout_height="wrap_content" 
        android:layout_weight="1" 
        android:textAppearance="?android:attr/textAppearanceLarge" 
        android:text="@string/title_android_to_network" 
        android:focusable="true" 
        android:focusableInTouchMode="true"/> 

       <android.support.design.widget.FloatingActionButton 
        android:id="@+id/button_refresh_network" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="@dimen/floating_action_button_margin" 
        android:src="@drawable/ic_fab_refresh" 
        android:contentDescription="@string/content_description_refresh" 
        app:elevation="4dp" 
        app:borderWidth="0dp" 
        app:fabSize="mini"/> 
      </LinearLayout> 
      <TableRow> 

       <ImageView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginRight="5dp" 
        android:layout_gravity="center_vertical" 
        android:id="@+id/android_network_state_image" 
        tools:src="@drawable/ic_check" 
        android:contentDescription="@string/content_description_diagnostic_status"/> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_gravity="center_vertical" 
        android:text="@string/label_state"/> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginLeft="5dp" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_gravity="center_vertical" 
        tools:text="Connected" 
        android:id="@+id/android_network_state"/> 

      </TableRow> 
     </TableLayout> 
    </ScrollView> 
</LinearLayout>