2016-03-08 3 views
0

Нижеприведенное приложение отлично работает на устройствах Android 4, но под Android 5 длительное нажатие (закрытого) счетчика не срабатывает при прослушивании. Зачем?Spinner OnLongClickListener не стреляет под Android 5.0

Я старательно исследовал эту проблему, но остаюсь в тупике. Я не могу найти точный дубликат. Нижеприведенный пример получен из рабочего приложения, которое широко использует эту технику. Идея состоит в том, что пользователь может вводить данные непосредственно в EditText или использовать Spinner. Чтобы использовать Spinner, вы (коротко) щелкните по закрытому Spinner, чтобы увидеть всплывающий список, (короткий), чтобы выбрать значение, и закрыть Spinner, и, наконец, (долго) щелкните закрытым Spinner, чтобы скопировать выделение в EditText.

Иррационально, под Android 5 (длинный) щелчок по закрытому счетчику открывает раскрывающийся список, аналогичный действию (короткого) щелчка. Когда длинный клик завершен (т. Е. Удалено пальцем), список снова закрывается, но слушатель все равно не срабатывает.

приложение работает на Galaxy S3 смартфон (4.3), терпит неудачу на смартфоне Galaxy S5 (5.0) и терпит неудачу на Galaxy Tab S2 (5.0.2) [Все устройства Samsung]

код Java является очень короткая. Все файлы .xml, необходимые для создания приложения, поставляются. Для полноты я добавил загадочный результат LOG (долгое нажатие) на Android-планшете 5.

SpinnerSample.java

package com.example.daz.spinnerbug; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.ArrayAdapter; 
import android.widget.EditText; 
import android.widget.Spinner; 

public class SpinnerSample extends Activity { 
    private String LOG = "SpinnerSample: "; 
    private EditText typeET; 
    private Spinner typeSP; 
    private View.OnLongClickListener LONGCLICK; 
    private String S_type[] = {"Type1", "type2", "type3df", "type4", "etc"}; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.spinnerlayout); 
     // NB: typeET values are uniquely defined via keyboard 
     // OR selected by "long-pressing" (closed) Spinner AFTER item selection 
     typeET = (EditText) findViewById(R.id.typeET); 
     typeSP = (Spinner) findViewById(R.id.typeSP); 
     spinners(); 
    } 

    public void spinners() { 
     // Define Listener (Triggered by LongPress on CLOSED spinner) 
     LONGCLICK = new View.OnLongClickListener() { 
      @Override 
      public boolean onLongClick(View v){ 
       // Following code never executes on Android 5 devices!!! 
       Spinner testSP = (Spinner) v; 
       Log.d(LOG + "LONGCLICK", testSP.getSelectedItem().toString()); 
       // Compare pointers using "==" [Do NOT use .equals()] 
       if (v == typeSP) { 
        typeET.setText(typeSP.getSelectedItem().toString()); 
        Log.d(LOG + "LONGCLICK", "'Type' Spinner successfully detected"); 
       } 
       return true; 
      } 
     }; 

     // Prime the Spinner 
     ArrayAdapter<String> AA_type = new ArrayAdapter<String>(this, R.layout.my_spinner, S_type); 
     typeSP.setAdapter(AA_type); 
     typeSP.setSelection(2, false);  // Arbitrary default for illustration only 
     typeSP.setClickable(true);   // Does NOT fix problem! 
     typeSP.setLongClickable(true);  // Does NOT fix problem! 
     typeSP.setOnLongClickListener(LONGCLICK); 

    } 
} 

spinnerlayout.xml

<?xml version="1.0" encoding="utf-8"?> 
<ScrollView android:id="@+id/spinnerSV" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" android:layout_weight="1"> 
    <LinearLayout 
     android:id="@+id/spinnerLL1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" android:padding="1dp"> 
     <TextView style="@style/wptedit_title" android:id="@+id/spinnerTV1" 
      android:text="Type:" > </TextView> 
     <LinearLayout android:id="@+id/spinerLL2" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal"> 
      <EditText style="@style/wptedit_data" android:id="@+id/typeET" 
       android:hint="type" 
       android:inputType="text" > </EditText> 
      <TextView style="@style/wptedit_title" android:id="@+id/spinnerTV2" 
       android:text="OR" > </TextView> 
      <Spinner 
       android:id="@+id/typeSP" 
       android:layout_width="0dp" 
       android:layout_height="match_parent" 
       android:layout_weight=".1" 
       android:background="@android:drawable/btn_dropdown" 
       android:spinnerStyle="@android:style/Widget.Spinner.DropDown" /> 
     </LinearLayout> 

    </LinearLayout> 
</ScrollView> 

my_spinner.xml

<?xml version="1.0" encoding="utf-8"?> 
<!-- C:\@ASDK\platforms\android-22\data\res\layout\simple_spinner_dropdown_item.xml --> 
<!-- CheckedTextView changed to TextView --> 
<!-- style="?android:attr/spinnerDropDownItemStyle" --> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/customSpinnerItemTextView" 
    android:singleLine="true" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:ellipsize="marquee" 
    android:textSize="18sp" 
    android:textAlignment="inherit" 
    android:textColor="#FF0000" 
    /> 

styles.xml

<resources> 

    <!-- Base application theme. --> 
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 
     <!-- Customize your theme here. --> 
    </style> 

    <style name="wptedit_title"> 
     <item name="android:layout_width">wrap_content</item> 
     <item name="android:layout_height">wrap_content</item> 
     <item name="android:textSize">14sp</item> 
     <item name="android:layout_marginTop">4dp</item> 
     <item name="android:layout_marginLeft">0dp</item> 
    </style> 

    <!-- Used for EditTexts --> 
    <style name="wptedit_data"> 
     <item name="android:layout_width">wrap_content</item> 
     <item name="android:layout_height">wrap_content</item> 
     <item name="android:textSize">18sp</item> 
     <item name="android:layout_marginTop">1dp</item> 
     <item name="android:layout_marginLeft">0dp</item> 
     <item name="android:imeOptions">actionNext</item> 
    </style> 

</resources> 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.daz.spinnerbug" > 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".SpinnerSample" 
      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> 

</manifest> 

LogCat

03-08 20:01:41.676 15125-15125/com.example.daz.spinnerbug D/ViewRootImpl﹕ ViewPostImeInputStage ACTION_DOWN 
03-08 20:01:42.021 15125-15125/com.example.daz.spinnerbug D/AbsListView﹕ Get MotionRecognitionManager 
03-08 20:01:42.031 15125-15125/com.example.daz.spinnerbug E/SRIB_DCS﹕ Returning true for title=PopupWindow:2dd64bf6 
03-08 20:01:42.071 15125-15125/com.example.daz.spinnerbug D/SRIB_DCS﹕ log_dcs ThreadedRenderer::initialize entered! 
03-08 20:01:42.071 15125-15145/com.example.daz.spinnerbug D/libEGL﹕ SRIB_DCS is_app_eligible 
03-08 20:01:42.071 15125-15145/com.example.daz.spinnerbug D/libEGL﹕ SRIB_DCS NOT Found in dcs list!!! proc=com.example.daz.spinnerbug 
03-08 20:01:42.071 15125-15145/com.example.daz.spinnerbug D/mali_winsys﹕ new_window_surface returns 0x3000, [1928x373]-format:1 
03-08 20:01:42.071 15125-15145/com.example.daz.spinnerbug D/OpenGLRenderer﹕ SRIB_DCS CanvasContext getDcsFlag flag=0 
03-08 20:01:42.071 15125-15145/com.example.daz.spinnerbug D/OpenGLRenderer﹕ SRIB_DCS OpenGLRenderer setDcsFlag flag=0 
03-08 20:01:42.091 15125-15145/com.example.daz.spinnerbug D/OpenGLRenderer﹕ SRIB_DCS OpenGLRenderer getDcsFlag flag=0 
03-08 20:01:43.846 15125-15125/com.example.daz.spinnerbug E/ViewRootImpl﹕ sendUserActionEvent() mView == null 
+0

Вы используете библиотеку app-compat? если не использовать его. он должен решить вашу проблему. – Jois

+0

@Jois В моей градиенте.build У меня есть (в зависимостях) compile 'com.android.support:appcompat-v7:22.2.1' Я также обновил свой SDK, чтобы получить последний Android 5.1. Я использую 'compileSdkVersion 22' –

+0

Ваша деятельность расширяет активность, но меняет ее на AppCompatActivity. он должен хорошо работать – Jois

ответ

0

this Обратитесь к вопросу. Я ранее не обращал на это внимания, поскольку было непонятно, пытался ли этот ажиотаж долгое нажатие на закрытый счетчик или на отдельные элементы в всплывающем списке. Кроме того, ответ @Almighty не был принят.

Но подклассов ArrayAdapter точно так, как описано мое приложение теперь ведет себя одинаково на Android 4 и 5. Вот мой новый файл:

// Custom ArrayAdapter to get (closed) Spinner OnLongClickListener working in Android 5. See: 
// https://stackoverflow.com/questions/26942205 
// Background: In Android 4 trapping a long press on a closed Spinner was trivial: 
//  Spinner.setOnLongClickListener(OnLongClickListener); 
// In android 5 this technique simply stopped working - never found out why! 
public class AA_Spinner<String> extends ArrayAdapter<String> { 
    private String LOG; 
    private EditText spinnerET; 
    private View.OnLongClickListener spinnerLC; 

    // NB: Our constructor extends ArrayAdapter with 3 more classes 
    // If EditText supplied, it will be updated using a standard default listener. 
    public AA_Spinner(Context context, int textViewResourceId, String[] items, 
         EditText et, 
         View.OnLongClickListener lcc, 
         String log) { 
     super(context, textViewResourceId, items); 
     this.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Android 
     this.setDropDownViewResource(R.layout.spinner_ddvr);       // Custom 
     if (et == null) { spinnerLC = lcc; return; } // Use supplied listener if no EditText 
     LOG = log; 
     spinnerET = et; 
     spinnerLC = new View.OnLongClickListener() { 
      @Override 
      public boolean onLongClick(View v) { // Default listener updates supplied EditText 
       TextView TV = (TextView) v; 
       if (Main.debug) 
        Log.d(LOG + "AA_Spinner", "replacing " + spinnerET.getText().toString() + " with " + TV.getText().toString()); 
       spinnerET.setText(TV.getText().toString()); 
       return true; 
      } 
     }; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     final View view = super.getView(position, convertView, parent); 
     if (spinnerLC != null && convertView == null) { //set listener only for newly created view 
      TextView tempTV = (TextView) view; 
      if (Main.debug) 
       Log.d(LOG + "getView", "Setting OnLongClickListener() for " + tempTV.getText().toString()); 
      view.setLongClickable(true); 
      view.setOnLongClickListener(spinnerLC); 
     } 
     return view; 
    } 

} 

Обратите внимание, что он поддерживает полное приложение, из которого была получена выборка.

Так что мне кажется, что Spinner.setOnLongClickListener (...) абсолютно бесполезен для Android 5. Пожалуйста, поправьте меня, если я ошибаюсь.