1
我使用ViewPager來顯示圖像。 ViewPager工作正常,但指標出現錯誤。當我滑動到最後一個條目時,指標只有大約70%的路程。看到屏幕:Viewpager:太小的指標或太多的標籤?
這就是問題所在。我不知道該指標是否太小,移動速度較慢或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;
}
}
}
的第一張截圖是來自平板電腦。下面是我的智能手機屏幕:
正如你可以看到智能手機的差距不是在平板電腦小得多。 任何想法可能是什麼問題?