0

Я пользуюсь этой библиотекой: https://github.com/yshrsmz/KeyboardVisibilityEvent, чтобы обнаружить, когда клавиатура открыта или закрыта, и это зависит от android:windowSoftInputMode="adjustResize", входящих в манифест Android.Android AdjustResize не изменяет размер правильно

Эта библиотека отлично работает, чтобы обнаруживать открытые и закрытые события мягкой клавиатуры, но мой контент выталкивается из поля зрения из-за параметра adjustResize.

  • Java:

    KeyboardVisibilityEvent.setEventListener(
         AddActivity.this, 
         new KeyboardVisibilityEventListener() { 
          @Override 
          public void onVisibilityChanged(boolean isOpen) { 
           // some code depending on keyboard visiblity status 
           if (noteEditText.isFocused()) { 
            if (isOpen) { 
             Log.d("KB", "Keyboard is open"); 
             noteEditText.setLines(12); 
             noteEditText.setCursorVisible(true); 
            } else { 
             Log.d("KB", "Keyboard is closed"); 
             noteEditText.setLines(50); 
             noteEditText.setCursorVisible(false); 
            } 
           } 
          } 
         }); 
    
    noteEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { 
        @Override 
        public void onFocusChange(View v, boolean hasFocus) { 
         Log.d("KB", "onFocusChange"); 
    
         if (firstStart) { 
          noteEditText.setLines(12); 
          noteEditText.setCursorVisible(true); 
          firstStart = false; 
         } 
        } 
    }); 
    
  • XML:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/add_record" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:padding="20dp" 
    android:windowSoftInputMode="stateHidden"> 
    
    <EditText 
        android:id="@+id/title_edittext" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:ems="10" 
        android:hint="@string/enter_title" 
        android:inputType="textCapSentences" 
        android:textColor="@color/fontPrimary" 
        android:theme="@style/EditTextCustomCursor"> 
    
        <requestFocus /> 
    </EditText> 
    
    <EditText 
        android:id="@+id/note_edittext" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:background="@null" 
        android:ellipsize="end" 
        android:gravity="top|left" 
        android:hint="@string/enter_note" 
        android:inputType="textCapSentences|textMultiLine" 
        android:lines="50" 
        android:maxLines="20" 
        android:minLines="5" 
        android:paddingLeft="5dp" 
        android:scrollHorizontally="false" 
        android:scrollbars="vertical" 
        android:textColor="@color/fontPrimary" 
        android:theme="@style/EditTextCustomCursor" /> 
    

Так это прекрасно работает, регулируя линии второго EditText так, то я набрав над клавиатурой, но когда я закрываю клавиатуру, прокрутите страницу до конца этого EditText и нажмите внизу, курсор EditText помещается туда, где я щелкнул, но затем он выталкивает первый EditText и Support ActionBar из вида и оставляет большой зазор внизу (как может быть (изображение 2) ниже, где выбрано «F», то есть нижняя часть EditText).

  • Желаемая эффект (все в правильном положении) Desired Effect

  • Фактический эффект (поддержка ActionBar и топ EditText перемещаются из поля зрения) Actual Effect

Я также пытался используя «adjustNothing» и выполняя следующие действия, но это, похоже, не работает, поскольку высота EditText не будет изменяться до тех пор, пока количество строк не изменится и онемение er строк изменяются только тогда, когда он знает, открыта или закрыта клавиатура.

private void setupListeners() { 

    final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content); 
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 

      View mainView = (LinearLayout) findViewById(R.id.add_record); 
      int heightDiff = mainView.getHeight() - noteEditText.getHeight(); 
      Log.d("KB", "HeightDiff: " + heightDiff); 
      if (heightDiff > 1000 || keyboardShown) { // 99% of the time the height diff will be due to a keyboard. 
       Log.d("KB", "Keyboard is open"); 

       if (isKeyboardVisible) { 
        noteEditText.setLines(12); 
        noteEditText.setCursorVisible(true); 
        noteEditText.requestLayout(); 
        isKeyboardVisible = false; 
       } 
      } else { 
       Log.d("KB", "Keyboard is closed"); 

       if (!isKeyboardVisible) { 
        noteEditText.setLines(50); 
        noteEditText.setCursorVisible(false); 
        noteEditText.requestLayout(); 
        isKeyboardVisible = true; 
       } 
      } 
     } 
    }); 

    noteEditText.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      numTimesClicked++; 
      Log.d("KB", "onClick: " + numTimesClicked); 

      if (clicked) { 
       // Run function 
       Log.d("KB", "clicked"); 
       InputMethodManager imm = (InputMethodManager) AddActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE); 

       if (imm.isAcceptingText()) { 
        Log.d("KB", "Software Keyboard was shown"); 
        isKeyboardVisible = true; 
        keyboardShown = true; 
       } else { 
        Log.d("KB", "Software Keyboard was not shown"); 
        isKeyboardVisible = false; 
        keyboardShown = false; 
       } 
      } else { 
       Log.d("KB", "scroll"); 
       clicked = true; 
       new Handler().postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         clicked = false; 
        } 
       }, 3 * 1000); 
      } 
     } 
    }); 

    noteEditText.setOnKeyListener(new View.OnKeyListener() { 
     @Override 
     public boolean onKey(View v, int keyCode, KeyEvent event) { 
      if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 
       Log.d("KB", "closeKeyboard"); 
       noteEditText.setLines(50); 
       noteEditText.setCursorVisible(false); 
       noteEditText.requestLayout(); 
       isKeyboardVisible = false; 
      } 
      return false; 
     } 
    }); 

Поэтому, как бы я идти о достижении желаемого эффекта подгонки линий EditText (при открытии клавиатуры и закрытой), а не толкая другой контент из поля зрения? Итак, поддержка ActionBar и первый EditText всегда остаются в одной и той же позиции, и только второй EditText настраивается, когда появляется мягкая клавиатура?

ответ

0

Теперь мне удалось решить это (не лучшее решение), но оно действительно работает. Верхний EditText и Support ActionBar теперь не выходят из режима просмотра, а второй EditText изменяет размеры независимо от того, какая строка выбрана.

Manifest:

<activity android:theme="@style/AppTheme" 
     android:name=".activities.AddActivity" 
     android:label="@string/add_record" 
     android:windowSoftInputMode="stateVisible|adjustResize" 
     android:parentActivityName=".MainActivity" 
     android:excludeFromRecents="true"/> 
    <activity android:theme="@style/AppTheme" 
     android:name=".activities.ModifyActivity" 
     android:label="@string/modify_record" 
     android:windowSoftInputMode="stateAlwaysHidden|adjustResize" 
     android:parentActivityName=".MainActivity" 
     android:excludeFromRecents="true"/> 

Java:

private void setupListeners() { 

    final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.add_record); 
    if (linearLayout != null) { 
     linearLayout.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Log.d(TAG, "Clicking ll"); 
       noteEditText.requestFocus(); 

       InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
       inputMethodManager.toggleSoftInputFromWindow(linearLayout.getApplicationWindowToken(), 
         InputMethodManager.SHOW_FORCED, 0); 
      } 
     }); 
    } 

    KeyboardVisibilityEvent.setEventListener(
      AddActivity.this, 
      new KeyboardVisibilityEventListener() { 
       @Override 
       public void onVisibilityChanged(boolean isOpen) { 
        // some code depending on keyboard visiblity status 
        Log.d(TAG, "Keyboard visibility changed"); 

        int currentLine = getCurrentCursorLine(noteEditText); 

        lineCount = noteEditText.getLineCount(); 

        if (isOpen && keyboardActuallyOpen) { 
         Log.d(TAG, "Keyboard is open"); 
         //keyboardActuallyClosed = false; 

          /* 
          scrollView.fullScroll(View.FOCUS_UP); 
          noteEditText.requestFocus(); 
          */ 

         if (currentLine < 25) { 

          getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); 

          scrollView.scrollTo(0, 0); 

          noteEditText.setMinLines(12); 
          noteEditText.setLines(12); 
          noteEditText.setMaxLines(12); 
          scrollView.scrollTo(0, 0); 

          noteEditText.setVerticalScrollBarEnabled(true); 
          scrollView.setVerticalScrollBarEnabled(false); 
          noteEditText.setCursorVisible(true); 

          scrollView.requestLayout(); 
          noteEditText.requestLayout(); 
         } else { 

          getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); 

          scrollView.scrollTo(0, 0); 
          noteEditText.setMinLines(12); 
          noteEditText.setLines(12); 
          noteEditText.setMaxLines(12); 
          scrollView.scrollTo(0, 0); 

          noteEditText.setVerticalScrollBarEnabled(true); 
          scrollView.setVerticalScrollBarEnabled(false); 
          noteEditText.setCursorVisible(true); 
         } 
        } else { 

         if (!keyboardActuallyOpen) { 


          lineCount = noteEditText.getLineCount(); 

          Log.d(TAG, "Keyboard is closed: " + lineCount); 
          noteEditText.setVerticalScrollBarEnabled(false); 
          scrollView.setVerticalScrollBarEnabled(true); 
          noteEditText.setCursorVisible(false); 

          noteEditText.setMinLines(lineCount); 
          noteEditText.setLines(lineCount); 
          noteEditText.setMaxLines(lineCount); 
          scrollView.scrollTo(0, 0); 

          keyboardActuallyOpen = false; 

          //scrollView.requestFocus(); 
          //setAdjustResize(1); 

          LinearLayout mainLayout = (LinearLayout) findViewById(R.id.add_record); 
          if (mainLayout != null) { 
           mainLayout.requestFocus(); 
          } 
         } 

        } 
       } 
      }); 

    noteEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { 
     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      Log.d(TAG, "onFocusChange"); 

      if (firstStart) { 
       scrollView.scrollTo(0, 0); 
       noteEditText.setLines(12); 
       noteEditText.setCursorVisible(true); 
       firstStart = false; 
      } 

      if (hasFocus) { 
       Log.d(TAG, "Has Focus"); 
       keyboardActuallyOpen = true; 
      } else { 
       Log.d(TAG, "Lost focus"); 
       keyboardActuallyOpen = false; 
       setAdjustResize(2); 
      } 
     } 
    }); 
    noteEditText.setOnKeyListener(new View.OnKeyListener() { 
     @Override 
     public boolean onKey(View v, int keyCode, KeyEvent event) { 
      if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 
       Log.d(TAG, "closeKeyboard"); 

       keyboardActuallyOpen = false; 

       noteEditText.setMinLines(lineCount); 
       noteEditText.setLines(lineCount); 
       noteEditText.setMaxLines(lineCount); 

       noteEditText.setVerticalScrollBarEnabled(false); 
       noteEditText.setCursorVisible(false); 
       noteEditText.requestLayout(); 

       scrollView.scrollTo(0, 0); 
       scrollView.setVerticalScrollBarEnabled(true); 
       scrollView.requestLayout(); 

       noteEditText.clearFocus(); 
      } 
      return false; 
     } 
    }); 


} 

Java (суб-классифицироваться EditText для клавиатуры кнопки закрытия нажат):

public class ExtendedEditText extends EditText { 

public ExtendedEditText(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

} 

public ExtendedEditText(Context context, AttributeSet attrs) { 
    super(context, attrs); 

} 

public ExtendedEditText(Context context) { 
    super(context); 

} 

@Override 
public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 
     dispatchKeyEvent(event); 
     return false; 
    } 
    return super.onKeyPreIme(keyCode, event); 
} 

}

XML

<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/add_scrollView" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:descendantFocusability="beforeDescendants" 
    android:focusableInTouchMode="true" 
    android:fillViewport="true"> 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/add_record" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" 
     android:padding="20dp" 
     android:focusable="true" 
     android:focusableInTouchMode="true"> 

     <EditText 
      android:id="@+id/title_edittext" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:ems="10" 
      android:hint="@string/enter_title" 
      android:inputType="textCapSentences" 
      android:textColor="@color/fontPrimary" 
      android:theme="@style/EditTextCustomCursor"> 
     </EditText> 

     <com.securenotes.utils.ExtendedEditText 
      android:id="@+id/note_edittext" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="@null" 
      android:ellipsize="end" 
      android:gravity="top|left" 
      android:hint="@string/enter_note" 
      android:inputType="textCapSentences|textMultiLine" 
      android:lines="50" 
      android:maxLines="20" 
      android:minLines="5" 
      android:paddingLeft="5dp" 
      android:scrollHorizontally="false" 
      android:scrollbars="vertical" 
      android:textColor="@color/fontPrimary" 
      android:theme="@style/EditTextCustomCursor" /> 

    </LinearLayout> 
</ScrollView> 
1

Я не уверен, но я верю. Если вы сохраните содержимое макета под номером ScrollView и каждый раз, когда пользователь вводит новую строку или новое слово, вы устанавливаете scrollView.scrollTo(0,0). Кроме того, вместо этой библиотеки, вы можете использовать ViewTreeObserver см here

Также вы можете управлять этим с помощью onFocusChangeListener(), которая является лучшей практикой.

+0

Благодарим за предложение с помощью ScrollView (поскольку это частично разрешило мою проблему), но по-прежнему вызывает одну последнюю проблему, если пользователь нажимает на строку без прокрутки (см. Мой ответ ниже). –

Смежные вопросы