2016-11-29 2 views
0

Ich verwende ein benutzerdefiniertes Snapping ScrollView in meiner App. Es erweitert HorizontalScrollView und überschreibt onTouchEvent(). Dies wird verwendet, um die untergeordneten Ansichten in der Mitte der ScrollView einzufangen. Es gibt auch einen führenden und einen nachgestellten Raum, die breit genug sind, damit das erste und das letzte Element in der Mitte platziert werden können.
ich zwei Klassenvariablen:Wie ändert man die Eigenschaften von Ansichten innerhalb von ScrollView während des Scrollens und ausgelöst durch Scrollen?

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 

ist hier mein 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); 
    } 

} 

Hier ist die XML-Datei, die ich

bin mit wollen
<?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> 

ich alle Elemente auf halbtransparent und nicht anklickbar, außer der aktiven Funktion. Im Moment können Sie blättern, und wenn Sie loslassen, rastet die Ansicht am nächsten Element ein. Dann ist das zuletzt eingerastete Element deaktiviert und das neue Element ist aktiviert aktiviert. Das funktioniert gut, aber ich möchte, dass der Benutzer sieht, an welchem ​​Element die ScrollView-Funktion aktiviert wird, wenn er den Finger hebt. Daher sollten die Berechnungen für die neue aktive Funktion und die Änderung der Transparenz während des Scrollens durchgeführt werden. Ist das möglich? Ich habe bereits versucht, den Code in einen Fall für MotionEvent.ACTION_MOVE zu schreiben, aber dann scrollte die Ansicht überhaupt nicht. Als ich den Code in einen Fall für MotionEvent.ACTION_SCROLL legte, passierte nichts und das Fangen wurde nicht ausgelöst.


Edit:
Zuerst habe ich den Code in einem zusätzlichen OnTouchListener, die überflüssig war, so dass ich jetzt die onTouchEvent Funktion außer Kraft setzen und bearbeiten entsprechend die Frage.

Antwort

0

Nach einigem weiterlesen und ein wenig versuchen & Fehler, ich kam mit der Lösung.
Also zuerst ist das benötigte MotionEvent ACTION_MOVE. Ich habe dies schon einmal versucht, aber es hat nicht funktioniert, als ich True und falsche auf eigene Faust zurückgegeben, nie die Implementierung der Oberklasse nennen. Also gebe ich immer super.onTouchEvent (Ereignis) zurück, da dies das Scrollen selbst behandelt.
Nur meine ACTION_UP und ACTION_CANCEL Behandlung ruft nicht an die Oberklasse, da dies normales Scrollen und kein Fangen tun würde.

@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); 
    } 

} 

Dann gab es ein letztes Problem zu lösen. ScrollView kann verstellt werden, so dass das Scrollen nicht aufhört, wenn Sie Ihren Finger heben. Diese interferred mit dem Schnappen, so dass ich overrid die fling() Methode:

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

Jetzt gibt es keine schleudert und die Scroll Snapps auf das am mittleren Elemente. Die Transparenzwerte werden beim Scrollen festgelegt, sodass der Benutzer immer weiß, zu welchem ​​Element die ScrollView-Funktion ausgeführt wird.

Verwandte Themen