Java tutorial
package com.github.antoniodisanto92.swipeselector; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Typeface; import android.graphics.drawable.ShapeDrawable; import android.os.Build; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.Arrays; /* * SwipeSelector library for Android * Copyright (c) 2016 Iiro Krankka (http://github.com/roughike). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ class SwipeAdapter extends PagerAdapter implements View.OnClickListener, ViewPager.OnPageChangeListener { private static final String STATE_CURRENT_POSITION = "STATE_CURRENT_POSITION"; private static final String TAG_CIRCLE = "TAG_CIRCLE"; // For the left and right buttons when they're not visible private static final String TAG_HIDDEN = "TAG_HIDDEN"; private final Context mContext; private final ViewPager mViewPager; private final ViewGroup mIndicatorContainer; private final LinearLayout.LayoutParams mCircleParams; private final ShapeDrawable mInActiveCircleDrawable; private final ShapeDrawable mActiveCircleDrawable; private Typeface mCustomTypeFace; private final int mTitleTextAppearance; private final int mDescriptionTextAppearance; private final int mDescriptionGravity; private final ImageView mLeftButton; private final ImageView mRightButton; private final int mSweetSixteen; private final int mContentLeftPadding; private final int mContentRightPadding; private OnSwipeItemSelectedListener mOnItemSelectedListener; private ArrayList<SwipeItem> mItems; private int mCurrentPosition; private SwipeAdapter(ViewPager viewPager, ViewGroup indicatorContainer, int indicatorSize, int indicatorMargin, int inActiveIndicatorColor, int activeIndicatorColor, int leftButtonResource, int rightButtonResource, ImageView leftButton, ImageView rightButton, String customFontPath, int titleTextAppearance, int descriptionTextAppearance, int descriptionGravity) { mContext = viewPager.getContext(); mViewPager = viewPager; mViewPager.addOnPageChangeListener(this); mIndicatorContainer = indicatorContainer; mCircleParams = new LinearLayout.LayoutParams(indicatorSize, indicatorSize); mCircleParams.leftMargin = indicatorMargin; mInActiveCircleDrawable = Indicator.newOne(indicatorSize, inActiveIndicatorColor); mActiveCircleDrawable = Indicator.newOne(indicatorSize, activeIndicatorColor); if (customFontPath != null && ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && !customFontPath.isEmpty()) || customFontPath.length() > 0)) { mCustomTypeFace = Typeface.createFromAsset(mContext.getAssets(), customFontPath); } mTitleTextAppearance = titleTextAppearance; mDescriptionTextAppearance = descriptionTextAppearance; mDescriptionGravity = getGravity(descriptionGravity); mLeftButton = leftButton; mLeftButton.setImageResource(leftButtonResource); mRightButton = rightButton; mRightButton.setImageResource(rightButtonResource); // Calculate paddings for the content so the left and right buttons // don't overlap. mSweetSixteen = (int) PixelUtils.dpToPixel(mContext, 16); mContentLeftPadding = ContextCompat.getDrawable(mContext, leftButtonResource).getIntrinsicWidth() + mSweetSixteen; mContentRightPadding = ContextCompat.getDrawable(mContext, rightButtonResource).getIntrinsicWidth() + mSweetSixteen; mLeftButton.setOnClickListener(this); mRightButton.setOnClickListener(this); mLeftButton.setTag(TAG_HIDDEN); mLeftButton.setClickable(false); setAlpha(0.0f, mLeftButton); } /** * Using the Java Builder Pattern here, because the SwipeSelector class was getting * messy and that's where most will look at. This class is protected, and contains no * methods that the users can use, so it's OK for this to look like absolute vomit. * <p/> * At least that's my opinion. But my opinions are always right. */ protected static class Builder { private ViewPager viewPager; private ViewGroup indicatorContainer; private int indicatorSize; private int indicatorMargin; private int inActiveIndicatorColor; private int activeIndicatorColor; private int leftButtonResource; private int rightButtonResource; private ImageView leftButton; private ImageView rightButton; private String customFontPath; private int titleTextAppearance; private int descriptionTextAppearance; private int descriptionGravity; protected Builder() { } protected Builder viewPager(ViewPager viewPager) { this.viewPager = viewPager; return this; } protected Builder indicatorContainer(ViewGroup indicatorContainer) { this.indicatorContainer = indicatorContainer; return this; } protected Builder indicatorSize(int indicatorSize) { this.indicatorSize = indicatorSize; return this; } protected Builder indicatorMargin(int indicatorMargin) { this.indicatorMargin = indicatorMargin; return this; } protected Builder inActiveIndicatorColor(int inActiveIndicatorColor) { this.inActiveIndicatorColor = inActiveIndicatorColor; return this; } protected Builder activeIndicatorColor(int activeIndicatorColor) { this.activeIndicatorColor = activeIndicatorColor; return this; } protected Builder leftButtonResource(int leftButtonResource) { this.leftButtonResource = leftButtonResource; return this; } protected Builder rightButtonResource(int rightButtonResource) { this.rightButtonResource = rightButtonResource; return this; } protected Builder leftButton(ImageView leftButton) { this.leftButton = leftButton; return this; } protected Builder rightButton(ImageView rightButton) { this.rightButton = rightButton; return this; } protected Builder customFontPath(String customFontPath) { this.customFontPath = customFontPath; return this; } protected Builder titleTextAppearance(int titleTextAppearance) { this.titleTextAppearance = titleTextAppearance; return this; } protected Builder descriptionTextAppearance(int descriptionTextAppearance) { this.descriptionTextAppearance = descriptionTextAppearance; return this; } protected Builder descriptionGravity(int descriptionGravity) { this.descriptionGravity = descriptionGravity; return this; } protected SwipeAdapter build() { return new SwipeAdapter(viewPager, indicatorContainer, indicatorSize, indicatorMargin, inActiveIndicatorColor, activeIndicatorColor, leftButtonResource, rightButtonResource, leftButton, rightButton, customFontPath, titleTextAppearance, descriptionTextAppearance, descriptionGravity); } } /** * Protected methods used by SwipeSelector */ protected void setOnItemSelectedListener(OnSwipeItemSelectedListener listener) { mOnItemSelectedListener = listener; } protected void setItems(SwipeItem... items) { // If there are SwipeItems constructed using String resources // instead of Strings, loop through all of them and get the // Strings. if (SwipeItem.checkForStringResources || SwipeItem.checkForDrawableResources) { ArrayList<SwipeItem> theRealOnes = new ArrayList<>(); for (SwipeItem item : items) { if (item.titleRes != -1) { item.title = mContext.getString(item.titleRes); } if (item.descriptionRes != -1) { item.description = mContext.getString(item.descriptionRes); } if (item.iconRes != -1) { item.icon = mContext.getResources().getDrawable(item.iconRes); } theRealOnes.add(item); } mItems = theRealOnes; // reset SwipeItem.checkForStringResources = false; } else { mItems = new ArrayList<>(Arrays.asList(items)); } mCurrentPosition = 0; setActiveIndicator(0); notifyDataSetChanged(); } protected SwipeItem getSelectedItem() { return mItems.get(mCurrentPosition); } protected void selectItemAt(int position, boolean animate) { if (position < 0 || position >= mItems.size()) { throw new IndexOutOfBoundsException( "This SwipeSelector does " + "not have an item at position " + position + "."); } mViewPager.setCurrentItem(position, animate); } protected void selectItemWithValue(Object value, boolean animate) { boolean itemExists = false; for (int i = 0; i < mItems.size(); i++) { if (mItems.get(i).value.equals(value)) { mViewPager.setCurrentItem(i, animate); itemExists = true; break; } } if (!itemExists) { throw new IllegalArgumentException( "This SwipeSelector " + "does not have an item with the given value " + value.toString() + "."); } } protected Bundle onSaveInstanceState() { Bundle bundle = new Bundle(); bundle.putInt(STATE_CURRENT_POSITION, mCurrentPosition); return bundle; } protected void onRestoreInstanceState(Bundle state) { mViewPager.setCurrentItem(state.getInt(STATE_CURRENT_POSITION), false); notifyDataSetChanged(); } /** * Override methods / listeners */ @Override public Object instantiateItem(ViewGroup container, int position) { SwipeItem slideItem = mItems.get(position); LinearLayout layout = null; switch (slideItem.iconGravity) { case CENTER: case DEFAULT: layout = (LinearLayout) View.inflate(mContext, R.layout.swipeselector_content_item, null); break; case LEFT: layout = (LinearLayout) View.inflate(mContext, R.layout.swipeselector_content_left_item, null); break; case RIGHT: layout = (LinearLayout) View.inflate(mContext, R.layout.swipeselector_content_right_item, null); break; } // GET VIEW ImageView icon = (ImageView) layout.findViewById(R.id.swipeselector_content_icon); TextView title = (TextView) layout.findViewById(R.id.swipeselector_content_title); TextView description = (TextView) layout.findViewById(R.id.swipeselector_content_description); // SET VIEW title.setText(slideItem.title); if (slideItem.description == null) { description.setVisibility(View.GONE); } else { description.setVisibility(View.VISIBLE); description.setText(slideItem.description); } if (slideItem.icon == null) { icon.setVisibility(View.GONE); } else { icon.setImageDrawable(slideItem.icon); icon.setVisibility(View.VISIBLE); } // We shouldn't get here if the typeface didn't exist. // But just in case, because we're paranoid. if (mCustomTypeFace != null) { title.setTypeface(mCustomTypeFace); description.setTypeface(mCustomTypeFace); } if (mTitleTextAppearance != -1) { setTextAppearanceCompat(title, mTitleTextAppearance); } if (mDescriptionTextAppearance != -1) { setTextAppearanceCompat(description, mDescriptionTextAppearance); } switch (slideItem.titleGravity) { case DEFAULT: case CENTER: title.setGravity(Gravity.CENTER); break; case LEFT: title.setGravity(Gravity.START); break; case RIGHT: title.setGravity(Gravity.END); break; } switch (slideItem.descriptionGravity) { case DEFAULT: if (mDescriptionGravity != -1) { description.setGravity(mDescriptionGravity); } else { description.setGravity(Gravity.CENTER); } break; case CENTER: description.setGravity(Gravity.CENTER); break; case LEFT: description.setGravity(Gravity.START); break; case RIGHT: description.setGravity(Gravity.END); break; } layout.setPadding(mContentLeftPadding, mSweetSixteen, mContentRightPadding, mSweetSixteen); container.addView(layout); return layout; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public int getCount() { return mItems != null ? mItems.size() : 0; } @Override public boolean isViewFromObject(View view, Object object) { return view.equals(object); } @Override public void onPageSelected(int position) { if (getCount() == 0) return; setActiveIndicator(position); handleLeftButtonVisibility(position); handleRightButtonVisibility(position); } @Override public void onClick(View v) { if (v.equals(mLeftButton) && mCurrentPosition >= 1) { mViewPager.setCurrentItem(mCurrentPosition - 1, true); } else if (v.equals(mRightButton) && mCurrentPosition <= getCount() - 1) { mViewPager.setCurrentItem(mCurrentPosition + 1, true); } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageScrollStateChanged(int state) { } /** * Private convenience methods used by this class. */ private void setActiveIndicator(int position) { if (mIndicatorContainer.findViewWithTag(TAG_CIRCLE) == null) { // No indicators yet, let's make some. Only run once per configuration. for (int i = 0; i < getCount(); i++) { ImageView indicator = (ImageView) View.inflate(mContext, R.layout.swipeselector_circle_item, null); if (i == position) { indicator.setImageDrawable(mActiveCircleDrawable); } else { indicator.setImageDrawable(mInActiveCircleDrawable); } indicator.setLayoutParams(mCircleParams); indicator.setTag(TAG_CIRCLE); mIndicatorContainer.addView(indicator); } return; } ImageView previousActiveIndicator = (ImageView) mIndicatorContainer.getChildAt(mCurrentPosition); ImageView nextActiveIndicator = (ImageView) mIndicatorContainer.getChildAt(position); previousActiveIndicator.setImageDrawable(mInActiveCircleDrawable); nextActiveIndicator.setImageDrawable(mActiveCircleDrawable); mCurrentPosition = position; if (mOnItemSelectedListener != null) { mOnItemSelectedListener.onItemSelected(getSelectedItem()); } } @SuppressWarnings("deprecation") private void setTextAppearanceCompat(TextView textView, int appearanceRes) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { textView.setTextAppearance(appearanceRes); } else { textView.setTextAppearance(textView.getContext(), appearanceRes); } } private int getGravity(int gravity) { if (gravity == -1) return -1; int realGravityValue; switch (gravity) { case 0: realGravityValue = Gravity.START; break; case 1: realGravityValue = Gravity.CENTER_HORIZONTAL; break; case 2: realGravityValue = Gravity.END; break; default: throw new IllegalArgumentException("Invalid value " + "specified for swipe_descriptionGravity. " + "Use \"left\", \"center\", \"right\" or leave " + "blank for default."); } return realGravityValue; } private void handleLeftButtonVisibility(int position) { if (position < 1) { mLeftButton.setTag(TAG_HIDDEN); mLeftButton.setClickable(false); animate(0, mLeftButton); } else if (TAG_HIDDEN.equals(mLeftButton.getTag())) { mLeftButton.setTag(null); mLeftButton.setClickable(true); animate(1, mLeftButton); } } private void handleRightButtonVisibility(int position) { if (position == getCount() - 1) { mRightButton.setTag(TAG_HIDDEN); mRightButton.setClickable(false); animate(0, mRightButton); } else if (TAG_HIDDEN.equals(mRightButton.getTag())) { mRightButton.setTag(null); mRightButton.setClickable(true); animate(1, mRightButton); } } private void animate(float alpha, ImageView button) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { button.animate().alpha(alpha).setDuration(120).start(); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { ObjectAnimator.ofFloat(button, "alpha", alpha == 1 ? 0 : alpha, alpha == 1 ? alpha : 0).setDuration(120) .start(); } else { setAlpha(alpha, button); } } @SuppressWarnings("deprecation") private void setAlpha(float alpha, ImageView button) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { button.setAlpha(alpha); } else { button.setAlpha((int) (alpha * 255)); } } }