2015-04-23 13 views
11

Mam następujące klasy:5,1 jak uniesieniem cień pod widokiem użyciu OnDraw metodę

class SlidingTabStrip extends LinearLayout { 

    private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 1; 
    private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26; 
    private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3; 
    private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5; 

    private final int mBottomBorderThickness; 
    private final Paint mBottomBorderPaint; 

    private final int mSelectedIndicatorThickness; 
    private final Paint mSelectedIndicatorPaint; 

    private final int mDefaultBottomBorderColor; 

    private int mSelectedPosition; 
    private float mSelectionOffset; 

    private SlidingTabLayout.TabColorizer mCustomTabColorizer; 
    private final SimpleTabColorizer mDefaultTabColorizer; 

    SlidingTabStrip(Context context) { 
     this(context, null); 
    } 

    SlidingTabStrip(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setWillNotDraw(false); 

     final float density = getResources().getDisplayMetrics().density; 

     TypedValue outValue = new TypedValue(); 
     context.getTheme().resolveAttribute(Color.parseColor("#000000"), outValue, true); 
     final int themeForegroundColor = outValue.data; 

     mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor, 
       DEFAULT_BOTTOM_BORDER_COLOR_ALPHA); 

     mDefaultTabColorizer = new SimpleTabColorizer(); 
     mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR); 

     mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density); 
     mBottomBorderPaint = new Paint(); 
     mBottomBorderPaint.setColor(mDefaultBottomBorderColor); 

     mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density); 
     mSelectedIndicatorPaint = new Paint(); 







    } 

    void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) { 
     mCustomTabColorizer = customTabColorizer; 
     invalidate(); 
    } 

    void setSelectedIndicatorColors(int... colors) { 
     // Make sure that the custom colorizer is removed 
     mCustomTabColorizer = null; 
     mDefaultTabColorizer.setIndicatorColors(colors); 
     invalidate(); 
    } 

    void onViewPagerPageChanged(int position, float positionOffset) { 
     mSelectedPosition = position; 
     mSelectionOffset = positionOffset; 
     invalidate(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     final int height = getHeight(); 
     final int childCount = getChildCount(); 
     final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null ? mCustomTabColorizer : mDefaultTabColorizer; 

     // Thick colored underline below the current selection 
     if (childCount > 0) { 
      View selectedTitle = getChildAt(mSelectedPosition); 
      int left = selectedTitle.getLeft(); 
      int right = selectedTitle.getRight(); 
      int color = tabColorizer.getIndicatorColor(mSelectedPosition); 

      if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) { 
       int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1); 
       if (color != nextColor) { 
        color = blendColors(nextColor, color, mSelectionOffset); 
       } 

       // Draw the selection partway between the tabs 
       View nextTitle = getChildAt(mSelectedPosition + 1); 
       left = (int) (mSelectionOffset * nextTitle.getLeft() + 
         (1.0f - mSelectionOffset) * left); 
       right = (int) (mSelectionOffset * nextTitle.getRight() + 
         (1.0f - mSelectionOffset) * right); 
      } 

      mSelectedIndicatorPaint.setColor(color); 

      canvas.drawRect(left, height - mSelectedIndicatorThickness, right,height, mSelectedIndicatorPaint); 
     } 

     // Thin underline along the entire bottom edge 
     canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint); 

    } 

    /** 
    * Set the alpha value of the {@code color} to be the given {@code alpha} value. 
    */ 
    private static int setColorAlpha(int color, byte alpha) { 
     return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); 
    } 

    /** 
    * Blend {@code color1} and {@code color2} using the given ratio. 
    * 
    * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend, 
    *    0.0 will return {@code color2}. 
    */ 
    private static int blendColors(int color1, int color2, float ratio) { 
     final float inverseRation = 1f - ratio; 
     float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation); 
     float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation); 
     float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation); 
     return Color.rgb((int) r, (int) g, (int) b); 
    } 

    private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer { 
     private int[] mIndicatorColors; 

     @Override 
     public final int getIndicatorColor(int position) { 
      return mIndicatorColors[position % mIndicatorColors.length]; 
     } 

     void setIndicatorColors(int... colors) { 
      mIndicatorColors = colors; 
     } 
    } 
} 

Poniższy wiersz służy do rysowania linii pod paska kart:

canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint); 

Gdybym ustawić następujące:

private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 10; 

uzyskać linię, która wygląda tak: enter image description here

Jednak chcę wyciągnąć go na zewnątrz paska kart, takich jak:

enter image description here

Wszelkie wskazówki, wytyczne w jaki sposób można to osiągnąć?

Dobra, jak sugeruje Rod, próbowałem użyć FrameLayout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <!-- android:paddingTop="?android:attr/actionBarSize" --> 

    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:foreground="@drawable/bottom_shadow" > 

     <com.example.SlidingTabLayout 
      android:id="@+id/sliding_tabs" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="@color/actionbar_bg" /> 
    </FrameLayout> 
    <!-- 
     <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:foreground="?android:windowContentOverlay" /> 
    --> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/pager" 
     android:layout_width="match_parent" 
     android:layout_height="0px" 
     android:layout_weight="1" 
     android:background="@android:color/white" /> 

</LinearLayout> 

Dzięki tej technice wynik pojawia się:

enter image description here

Odpowiedz

5

cant faktycznie dodać rozwijanej cień w obrębie karty przy użyciu jej OnDraw.

musisz opakować zawartość w FrameLayout i użyć jej android:foreground i ustawić cień, który można znaleźć w ikonach projektowania materiałów, aby emulować cień na nim.

enter image description here To jest dziewiąty obraz poprawki. upewnić się, czy użyć tego powinno być położenie w xhdpi rozciągliwej folderu z rozszerzeniem jako name.9.png

Sample XML dla dodawania powyższy obrazek, aby emulować cień na górnej części widoku:

<FrameLayout 
    android:id="@+id/fl_fragment_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_below="@id/tool_bar" 
    android:foreground="@drawable/bottom_shadow"> 

     // your view here 

</FrameLayout> 

Edytuj:

+0

Dzięki stary, próbowałem tego wcześniej, ale to nie daje mi efektu elewacji, chcę, żeby lista przewinęła się pod cieniem. – User3

+0

Och, zapomniałem, że krępownik xhdpi, o którym wspomniałeś, spróbuje jeszcze raz! – User3

+0

@ User3 Powinien działać, ponieważ użyłem go wczoraj, a widok jest pod spodem dokładnie tak, jak chciałeś. –

2

Prawdopodobnie znajdziesz this question quite useful.

kodem przeznaczonym:

Rect newRect = canvas.getClipBounds(); 
newRect.inset(-5, -5) // Make the Rect larger 

canvas.clipRect (myNewRect, Region.Op.REPLACE); 
// Draw shadow here 

Canvas jest w stanie wyciągnąć na zewnątrz siebie, zwiększając swój obwiedni tnącej (ujemnie insetting). Następnie możesz narysować cień w dolnej krawędzi.

+0

Dzięki kolego, sprawdzę to! – User3

Powiązane problemy