2016-08-17 85 views
1

我使用ViewPager來顯示圖像。 ViewPager工作正常,但指標出現錯誤。當我滑動到最後一個條目時,指標只有大約70%的路程。看到屏幕:Viewpager:太小的指標或太多的標籤?

enter image description here

這就是問題所在。我不知道該指標是否太小,移動速度較慢或viewpager中存在另一個隱藏條目,但由於我無法向右滑動,因此我認爲存在指標大小或移動或類似的錯誤。

這是我initializ我viewpager:

this.viewPager.setId(R.id.image_inspiration_pager); 
this.viewPager.setClipToPadding(false); 
this.viewPager.setPadding(0, 0, ((int) HelperPixel.convertDpToPixel(this.getContext(), 48)), 0); 
this.viewPager.setAdapter(adapter); 
this.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

    private static final float thresholdOffset = 0.5f; 
    private boolean scrollStarted = false; 
    private boolean checkDirection = false; 

    @Override 
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     if (position == 0) { 
      viewPager.setPadding(0, 0, ((int) HelperPixel.convertDpToPixel(getContext(), 48)), 0); 

      return; 
     } else if (position == (adapter.getCount() - 1)) { 
      viewPager.setPadding(((int) HelperPixel.convertDpToPixel(getContext(), 48)), 0, 0, 0); 

      return; 
     } 

     if (this.checkDirection) { 
      if (thresholdOffset > positionOffset) { 
       viewPager.setPadding(0, 0, ((int) HelperPixel.convertDpToPixel(getContext(), 48)), 0); 
      } else { 
       viewPager.setPadding(((int) HelperPixel.convertDpToPixel(getContext(), 48)), 0, 0, 0); 
      } 

      this.checkDirection = false; 
     } 
    } 

    @Override 
    public void onPageSelected(int position) {} 

    @Override 
    public void onPageScrollStateChanged(int state) { 
     if (!this.scrollStarted && state == ViewPager.SCROLL_STATE_DRAGGING) { 
      this.scrollStarted = true; 
      this.checkDirection = true; 
     } else { 
      this.scrollStarted = false; 
     } 
    } 
}); 

TabLayout的執行情況:

public class TabsSlidingLayout extends HorizontalScrollView { 
    private static final int TITLE_OFFSET_DIPS = 24; 
    private static final int TAB_VIEW_PADDING_DIPS = 16; 
    private static final int TAB_VIEW_TEXT_SIZE_SP = 14; 
    private int titleOffset; 
    private int tabViewLayoutId; 
    private int tabViewTextViewId; 
    private ViewPager viewPager; 
    private ViewPager.OnPageChangeListener pageChangeListener; 
    private final TabsSlidingStrip tabStrip; 

    public TabsSlidingLayout(Context context) { 
     this(context, null); 
    } 

    public TabsSlidingLayout(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

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

     this.setHorizontalScrollBarEnabled(false); 
     this.setFillViewport(true); 
     this.titleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density); 
     this.tabStrip = new TabsSlidingStrip(context); 

     this.addView(this.tabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
    } 

    public void setCustomBackgroundColor(int color) { 
     this.tabStrip.setBackgroundColor(color); 
    } 

    public void setCustomTabColorizer(TabColorizer tabColorizer) { 
     this.tabStrip.setCustomTabColorizer(tabColorizer); 
    } 

    public void setSelectedIndicatorColors(int... colors) { 
     this.tabStrip.setSelectedIndicatorColors(colors); 
    } 

    public void setDividerColors(int... colors) { 
     this.tabStrip.setDividerColors(colors); 
    } 

    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { 
     this.pageChangeListener = listener; 
    } 

    public void setCustomTabView(int layoutResId, int textViewId) { 
     this.tabViewLayoutId = layoutResId; 
     this.tabViewTextViewId = textViewId; 
    } 

    public void setViewPager(ViewPager viewPager) { 
     this.tabStrip.removeAllViews(); 

     this.viewPager = viewPager; 

     if (this.viewPager != null) { 
      this.viewPager.addOnPageChangeListener(new InternalViewPagerListener()); 
      this.populateTabStrip(); 
     } 
    } 

    protected TextView createDefaultTabView(Context context) { 
     TextView textView = new TextView(context); 
     textView.setGravity(Gravity.CENTER); 
     textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP); 
     textView.setTypeface(Typeface.DEFAULT_BOLD); 
     textView.setTextColor(ContextCompat.getColor(context, R.color.white)); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      TypedValue outValue = new TypedValue(); 

      this.getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true); 

      textView.setBackgroundResource(outValue.resourceId); 
     } 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
      textView.setAllCaps(true); 
     } 

     int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density); 

     textView.setPadding(padding, padding, padding, padding); 

     return textView; 
    } 

    private void populateTabStrip() { 
     final PagerAdapter adapter = this.viewPager.getAdapter(); 
     final View.OnClickListener tabClickListener = new TabClickListener(); 

     for (int i = 0; i < adapter.getCount(); i++) { 
      View tabView = null; 
      TextView tabTitleView = null; 

      if (this.tabViewLayoutId != 0) { 
       tabView = LayoutInflater.from(this.getContext()).inflate(this.tabViewLayoutId, this.tabStrip, false); 
       tabTitleView = (TextView) tabView.findViewById(this.tabViewTextViewId); 
      } 

      if (tabView == null) { 
       tabView = createDefaultTabView(this.getContext()); 
      } 

      if (tabTitleView == null && TextView.class.isInstance(tabView)) { 
       tabTitleView = (TextView) tabView; 
      } 

      tabTitleView.setText(adapter.getPageTitle(i)); 
      tabView.setOnClickListener(tabClickListener); 

      this.tabStrip.addView(tabView); 
     } 
    } 

    @Override 
    protected void onAttachedToWindow() { 
     super.onAttachedToWindow(); 

     if (this.viewPager != null) { 
      this.scrollToTab(this.viewPager.getCurrentItem(), 0); 
     } 
    } 

    private void scrollToTab(int tabIndex, int positionOffset) { 
     final int tabStripChildCount = this.tabStrip.getChildCount(); 

     if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) { 
      return; 
     } 

     View selectedChild = this.tabStrip.getChildAt(tabIndex); 

     if (selectedChild != null) { 
      int targetScrollX = selectedChild.getLeft() + positionOffset; 

      if (tabIndex > 0 || positionOffset > 0) { 
       targetScrollX -= this.titleOffset; 
      } 

      this.scrollTo(targetScrollX, 0); 
     } 
    } 

    public interface TabColorizer { 

     int getIndicatorColor(int position); 

     int getDividerColor(int position); 
    } 

    private class InternalViewPagerListener implements ViewPager.OnPageChangeListener { 
     private int scrollState = -1; 

     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      int tabStripChildCount = tabStrip.getChildCount(); 

      if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) { 
       return; 
      } 

      tabStrip.onViewPagerPageChanged(position, positionOffset); 

      View selectedTitle = tabStrip.getChildAt(position); 
      int extraOffset = (selectedTitle != null) ? (int) (positionOffset * selectedTitle.getWidth()) : 0; 

      scrollToTab(position, extraOffset); 

      if (pageChangeListener != null) { 
       pageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 
      } 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 
      this.scrollState = state; 

      if (pageChangeListener != null) { 
       pageChangeListener.onPageScrollStateChanged(state); 
      } 
     } 

     @Override 
     public void onPageSelected(int position) { 
      if (this.scrollState == ViewPager.SCROLL_STATE_IDLE) { 
       tabStrip.onViewPagerPageChanged(position, 0f); 
       scrollToTab(position, 0); 
      } 

      if (pageChangeListener != null) { 
       pageChangeListener.onPageSelected(position); 
      } 
     } 

    } 

    private class TabClickListener implements View.OnClickListener { 
     @Override 
     public void onClick(View view) { 
      for (int i = 0; i < tabStrip.getChildCount(); i++) { 
       if (view == tabStrip.getChildAt(i)) { 
        viewPager.setCurrentItem(i); 

        return; 
       } 
      } 
     } 
    } 
} 

TabSlidingStrip實現:

class TabsSlidingStrip extends LinearLayout { 
    private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0; 
    private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26; 
    private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 2; 
    private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFFFFFFFF; 
    private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 0; 
    private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20; 
    private static final float DEFAULT_DIVIDER_HEIGHT = 0.0f; 
    private final int bottomBorderThickness; 
    private final Paint bottomBorderPaint; 
    private final int selectedIndicatorThickness; 
    private final Paint selectedIndicatorPaint; 
    private final Paint dividerPaint; 
    private final float dividerHeight; 
    private int selectedPosition; 
    private float selectionOffset; 
    private TabsSlidingLayout.TabColorizer customTabColorizer; 
    private final SimpleTabColorizer defaultTabColorizer; 

    public TabsSlidingStrip(Context context) { 
     this(context, null); 
    } 

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

     this.setWillNotDraw(false); 

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

     TypedValue outValue = new TypedValue(); 

     context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true); 

     final int themeForegroundColor = outValue.data; 

     this.setBackgroundColor(ContextCompat.getColor(context, R.color.primaryColor)); 
     this.defaultTabColorizer = new SimpleTabColorizer(); 
     this.defaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR); 
     this.defaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor, DEFAULT_DIVIDER_COLOR_ALPHA)); 
     this.bottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density); 
     this.bottomBorderPaint = new Paint(); 
     this.bottomBorderPaint.setColor(setColorAlpha(themeForegroundColor, DEFAULT_BOTTOM_BORDER_COLOR_ALPHA)); 
     this.selectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density); 
     this.selectedIndicatorPaint = new Paint(); 
     this.dividerHeight = DEFAULT_DIVIDER_HEIGHT; 
     this.dividerPaint = new Paint(); 
     this.dividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density)); 
    } 

    void setCustomTabColorizer(TabsSlidingLayout.TabColorizer customTabColorizer) { 
     this.customTabColorizer = customTabColorizer; 

     this.invalidate(); 
    } 

    void setSelectedIndicatorColors(int... colors) { 
     this.customTabColorizer = null; 
     this.defaultTabColorizer.setIndicatorColors(colors); 

     this.invalidate(); 
    } 

    void setDividerColors(int... colors) { 
     this.customTabColorizer = null; 
     this.defaultTabColorizer.setDividerColors(colors); 

     this.invalidate(); 
    } 

    void onViewPagerPageChanged(int position, float positionOffset) { 
     this.selectedPosition = position; 
     this.selectionOffset = positionOffset; 

     this.invalidate(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     final int height = this.getHeight(); 
     final int childCount = this.getChildCount(); 
     final int dividerHeightPx = (int) (Math.min(Math.max(0f, this.dividerHeight), 1f) * height); 
     final TabsSlidingLayout.TabColorizer tabColorizer = this.customTabColorizer != null ? this.customTabColorizer : this.defaultTabColorizer; 

     if (childCount > 0) { 
      View selectedTitle = getChildAt(this.selectedPosition); 
      int left = selectedTitle.getLeft(); 
      int right = selectedTitle.getRight(); 
      int color = tabColorizer.getIndicatorColor(this.selectedPosition); 

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

       View nextTitle = getChildAt(this.selectedPosition + 1); 

       left = (int) (this.selectionOffset * nextTitle.getLeft() + (1.0f - this.selectionOffset) * left); 
       right = (int) (this.selectionOffset * nextTitle.getRight() + (1.0f - this.selectionOffset) * right); 
      } 

      this.selectedIndicatorPaint.setColor(color); 

      canvas.drawRect(left, height - this.selectedIndicatorThickness, right, height, this.selectedIndicatorPaint); 
     } 

     canvas.drawRect(0, height - this.bottomBorderThickness, this.getWidth(), height, this.bottomBorderPaint); 

     int separatorTop = (height - dividerHeightPx)/2; 

     for (int i = 0; i < childCount - 1; i++) { 
      View child = getChildAt(i); 

      this.dividerPaint.setColor(tabColorizer.getDividerColor(i)); 

      canvas.drawLine(child.getRight(), separatorTop, child.getRight(), separatorTop + dividerHeightPx, this.dividerPaint); 
     } 
    } 

    private static int setColorAlpha(int color, byte alpha) { 
     return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); 
    } 

    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 TabsSlidingLayout.TabColorizer { 
     private int[] indicatorColors; 
     private int[] dividerColors; 

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

     void setIndicatorColors(int... colors) { 
      this.indicatorColors = colors; 
     } 

     @Override 
     public final int getDividerColor(int position) { 
      return this.dividerColors[position % this.dividerColors.length]; 
     } 

     void setDividerColors(int... colors) { 
      this.dividerColors = colors; 
     } 
    } 
} 

的第一張截圖是來自平板電腦。下面是我的智能手機屏幕:

enter image description here

正如你可以看到智能手機的差距不是在平板電腦小得多。 任何想法可能是什麼問題?

回答

0

下面的代碼添加到的createDefaultTabView底部:

WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
    Display display = windowManager.getDefaultDisplay(); 
    Point size = new Point(); 

    display.getSize(size); 

    textView.setWidth(size.x/this.viewPager.getAdapter().getCount());