2016-11-29 2 views
0

Я использую настраиваемый ScrollView в моем приложении. Он расширяет HorizontalScrollView и переопределяет onTouchEvent(). Это используется для привязки дочерних представлений в середине ScrollView. Существует также ведущее и конечное пространство, которые достаточно широки, поэтому первый и последний элементы могут быть размещены посередине.
Я использую две переменные класса:Как изменить свойства просмотров внутри ScrollView при прокрутке и активации при прокрутке?

int mActiveFeature //Position of the element nearest to the middle, initially set to 1 
List<Integer> mAvailableItems //IDs of contained menu elements in order without the spaces 

Вот мой onTouchEvent:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    final int menuItemCount = this.mAvailableItems.size(); 
    switch(event.getAction()) { 
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_CANCEL: 
      float scrollX = getScrollX(); 
      float layoutWidth = 
        SnappingScroll.this.getWidth(); 
      float featureWidth = 
        (int) getResources().getDimension(R.dimen.item_width); 
      float spaceWidth = 
        (int) getResources().getDimension(R.dimen.space_width); 

      View oldItem = 
        findViewById(
          SnappingScroll.this.mAvailableItems.get(
            SnappingScroll.this.mActiveFeature - 1 
          ) 
        ); 
      oldItem.setAlpha(0.5f); 
      oldItem.setClickable(false); 

      SnappingScroll.this.mActiveFeature = (int) Math.min(
        Math.round((scrollX - spaceWidth + (layoutWidth/2) + (featureWidth/2))/featureWidth), 
        (float) menuItemCount 
      ); 

      View newItem = 
        findViewById(
          SnappingScroll.this.mAvailableItems.get(
            SnappingScroll.this.mActiveFeature - 1 
          ) 
        ); 
      newItem.setAlpha(1.0f); 
      newItem.setClickable(true); 

      int scrollTo = (int) (
        SnappingScroll.this.mActiveFeature * featureWidth 
          + spaceWidth 
          - layoutWidth/2 
          - featureWidth/2 
      ); 
      smoothScrollTo(scrollTo, 0); 
      return true; 
     default: 
      return super.onTouchEvent(event); 
    } 

} 

Вот файл XML Я использую

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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:background="@android:color/black" 
    android:orientation="vertical"> 
    <com.example.SnappingScroll 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_gravity="center_horizontal"> 
     <LinearLayout 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:gravity="center_vertical"> 
      <Space 
       android:id="@+id/leading_space" 
       android:layout_width="@dimen/space_width" 
       android:layout_height="match_parent" /> 
      <ImageView 
        android:id="@+id/item_1" 
        android:layout_width="@dimen/item_width" 
        android:layout_height="match_parent" 
        android:alpha="0.5" 
        android:clickable="false" 
        android:onClick="clickFunction" 
        android:src="@drawable/m_1"/> 
      <ImageView 
        android:id="@+id/item_2" 
        android:layout_width="@dimen/item_width" 
        android:layout_height="match_parent" 
        android:alpha="0.5" 
        android:clickable="false" 
        android:onClick="clickFunction" 
        android:src="@drawable/m_2"/> 
      <ImageView 
        android:id="@+id/item_3" 
        android:layout_width="@dimen/item_width" 
        android:layout_height="match_parent" 
        android:alpha="0.5" 
        android:clickable="false" 
        android:onClick="clickFunction" 
        android:src="@drawable/m_3"/> 
      <Space 
       android:id="@+id/trailing_space" 
       android:layout_width="@dimen/space_width" 
       android:layout_height="match_parent" /> 
     </LinearLayout> 
    </com.example.SnappingScroll> 
</LinearLayout> 

Я хочу, чтобы все элементы на половину прозрачности и не кликабельны, кроме активной функции. На данный момент вы можете прокручивать, и, когда вы отпускаете, объект View привязывается к ближайшему элементу. Затем последний привязанный к элементу деактивирован, а новый привязанный к элементу активирован. Это прекрасно работает, но я хочу, чтобы пользователь увидел, к какому элементу привязывается ScrollView, когда он поднимает палец. Таким образом, расчеты для новой активной функции и изменения прозрачности должны выполняться при прокрутке. Это возможно? Я уже пытался поставить код в случае для MotionEvent.ACTION_MOVE, но тогда View не прокручивался вообще. Поскольку я помещал код в случай для MotionEvent.ACTION_SCROLL, ничего не происходило, и привязка не срабатывала.


Edit:
Сначала я поставил код в дополнительном OnTouchListener, который был излишним, так что теперь я переопределить функцию onTouchEvent и редактировал вопрос соответственно.

ответ

0

После некоторого дальнейшего чтения и немного попыток ошибки &, я придумал решение.
Итак, необходимо, чтобы MotionEvent был ACTION_MOVE. Я пробовал это раньше, но это не сработало, поскольку я вернул true и false сам по себе, никогда не вызывающий реализацию суперкласса. Поэтому я всегда возвращаю super.onTouchEvent (event), так как это обрабатывает прокрутку.
Только мои ACTION_UP и Обработка ACTION_CANCEL не вызывает суперкласс, так как это будет нормальная прокрутка и отсутствие привязки.

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    final int menuItemCount = this.mAvailableItems.size(); 

    int oldFeature = this.mActiveFeature; 
    float scrollX = getScrollX(); 
    float layoutWidth = 
      SnappingScroll.this.getWidth(); 
    float featureWidth = 
      (int) getResources().getDimension(R.dimen.item_width); 
    float spaceWidth = 
      (int) getResources().getDimension(R.dimen.space_width); 
    View newItem, oldItem; 

    switch(event.getAction()) { 
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_CANCEL: 
      newItem = 
        findViewById(
          SnappingScroll.this.mAvailableItems.get(
            SnappingScroll.this.mActiveFeature - 1 
          ) 
        ); 
      newItem.setClickable(true); 

      int scrollTo = (int) (
        SnappingScroll.this.mActiveFeature * featureWidth 
          + spaceWidth 
          - layoutWidth/2 
          - featureWidth/2 
      ); 
      smoothScrollTo(scrollTo, 0); 
      return true; 
     case MotionEvent.ACTION_MOVE: 
      SnappingScroll.this.mActiveFeature = (int) Math.min(
        Math.round((scrollX - spaceWidth + (layoutWidth/2) + (featureWidth/2))/featureWidth), 
        (float) menuItemCount 
      ); 

      if(oldFeature == this.mActiveFeature) { 
       return super.onTouchEvent(event); 
      } else { 
       oldItem = 
         findViewById(
           SnappingScroll.this.mAvailableItems.get(
             oldFeature - 1 
           ) 
         ); 
       oldItem.setAlpha(0.5f); 
       oldItem.setClickable(false); 

       newItem = 
         findViewById(
           SnappingScroll.this.mAvailableItems.get(
             SnappingScroll.this.mActiveFeature - 1 
           ) 
         ); 
       newItem.setAlpha(1.0f); 
       return super.onTouchEvent(event); 
      } 
     default: 
      return super.onTouchEvent(event); 
    } 

} 

Тогда возникла одна последняя проблема. ScrollView можно отбросить, поэтому прокрутка не останавливается, когда вы поднимаете палец. Это interferred с защелкиванием, так что я overrid в интрижки() метода:

@Override 
public void fling (int velocityY) 
{ 
    super.fling(0); 
} 

Теперь, нет никакого бросая и snapps Scrollview до самого среднего элемента. Значения прозрачности устанавливаются во время прокрутки, поэтому пользователь всегда знает, к какому элементу будет привязан ScrollView.

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