Java tutorial
/* * The MIT License (MIT) * * Copyright (c) 2015 baoyongzhang <baoyz94@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.wdd.app.android.catgirl.views; import android.content.Context; import android.content.res.Resources; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewCompat; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import org.wdd.app.android.catgirl.R; import java.lang.reflect.Method; import java.util.List; /** * android-ActionSheet * Created by baoyz on 15/6/30. */ @SuppressWarnings("ResourceType") public class ActionSheet extends Fragment implements View.OnClickListener { private static final String ARG_CANCEL_BUTTON_TITLE = "cancel_button_title"; private static final String ARG_OTHER_BUTTON_TITLES = "other_button_titles"; private static final String ARG_CANCELABLE_ONTOUCHOUTSIDE = "cancelable_ontouchoutside"; private static final int CANCEL_BUTTON_ID = 100; private static final int BG_VIEW_ID = 10; private static final int TRANSLATE_DURATION = 200; private static final int ALPHA_DURATION = 300; private static final String EXTRA_DISMISSED = "extra_dismissed"; private boolean mDismissed = true; private ActionSheetListener mListener; private View mView; private LinearLayout mPanel; private ViewGroup mGroup; private View mBg; private boolean isCancel = true; public void show(final FragmentManager manager, final String tag) { if (!mDismissed || manager.isDestroyed()) { return; } mDismissed = false; new Handler().post(new Runnable() { public void run() { FragmentTransaction ft = manager.beginTransaction(); ft.add(ActionSheet.this, tag); ft.addToBackStack(null); ft.commitAllowingStateLoss(); } }); } public void dismiss() { if (mDismissed) { return; } mDismissed = true; new Handler().post(new Runnable() { public void run() { getFragmentManager().popBackStack(); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.remove(ActionSheet.this); ft.commitAllowingStateLoss(); } }); } @Override public void onSaveInstanceState(Bundle outState) { outState.putBoolean(EXTRA_DISMISSED, mDismissed); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { mDismissed = savedInstanceState.getBoolean(EXTRA_DISMISSED); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive()) { View focusView = getActivity().getCurrentFocus(); if (focusView != null) { imm.hideSoftInputFromWindow(focusView.getWindowToken(), 0); } } mView = createView(); mGroup = (ViewGroup) getActivity().getWindow().getDecorView(); createItems(); mGroup.addView(mView); mBg.startAnimation(createAlphaInAnimation()); mPanel.startAnimation(createTranslationInAnimation()); return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onDestroyView() { mPanel.startAnimation(createTranslationOutAnimation()); mBg.startAnimation(createAlphaOutAnimation()); mView.postDelayed(new Runnable() { @Override public void run() { mGroup.removeView(mView); } }, ALPHA_DURATION); if (mListener != null) { mListener.onDismiss(this, isCancel); } super.onDestroyView(); } private Animation createTranslationInAnimation() { int type = TranslateAnimation.RELATIVE_TO_SELF; TranslateAnimation an = new TranslateAnimation(type, 0, type, 0, type, 1, type, 0); an.setDuration(TRANSLATE_DURATION); return an; } private Animation createAlphaInAnimation() { AlphaAnimation an = new AlphaAnimation(0, 1); an.setDuration(ALPHA_DURATION); return an; } private Animation createTranslationOutAnimation() { int type = TranslateAnimation.RELATIVE_TO_SELF; TranslateAnimation an = new TranslateAnimation(type, 0, type, 0, type, 0, type, 1); an.setDuration(TRANSLATE_DURATION); an.setFillAfter(true); return an; } private Animation createAlphaOutAnimation() { AlphaAnimation an = new AlphaAnimation(1, 0); an.setDuration(ALPHA_DURATION); an.setFillAfter(true); return an; } private View createView() { FrameLayout parent = new FrameLayout(getContext()); parent.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); mBg = new View(getContext()); mBg.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); mBg.setBackgroundColor(Color.parseColor("#4e000000")); mBg.setId(ActionSheet.BG_VIEW_ID); mBg.setOnClickListener(this); mPanel = new LinearLayout(getContext()); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.BOTTOM; mPanel.setLayoutParams(params); mPanel.setOrientation(LinearLayout.VERTICAL); parent.setPadding(0, 0, 0, getNavBarHeight(getActivity())); parent.addView(mBg); parent.addView(mPanel); return parent; } public int getNavBarHeight(Context context) { int navigationBarHeight = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Resources rs = context.getResources(); int id = rs.getIdentifier("navigation_bar_height", "dimen", "android"); if (id > 0 && checkDeviceHasNavigationBar(context)) { navigationBarHeight = rs.getDimensionPixelSize(id); } } return navigationBarHeight; } private boolean checkDeviceHasNavigationBar(Context context) { boolean hasNavigationBar = false; Resources rs = context.getResources(); int id = rs.getIdentifier("config_showNavigationBar", "bool", "android"); if (id > 0) { hasNavigationBar = rs.getBoolean(id); } try { Class systemPropertiesClass = Class.forName("android.os.SystemProperties"); Method m = systemPropertiesClass.getMethod("get", String.class); String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys"); if ("1".equals(navBarOverride)) { hasNavigationBar = false; } else if ("0".equals(navBarOverride)) { hasNavigationBar = true; } } catch (Exception e) { e.printStackTrace(); } return hasNavigationBar; } private void createItems() { String[] titles = getOtherButtonTitles(); if (titles != null) { for (int i = 0; i < titles.length; i++) { Button bt = new Button(getContext()); bt.setClickable(true); bt.setId(CANCEL_BUTTON_ID + i + 1); bt.setOnClickListener(this); bt.setBackgroundResource(R.drawable.common_list_item_bg); bt.setText(titles[i]); bt.setTextColor(Color.parseColor("#1E82FF")); bt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); bt.setGravity(Gravity.CENTER); ViewCompat.setElevation(bt, 0); mPanel.addView(bt, new LayoutParams(LayoutParams.MATCH_PARENT, dp2px(getContext(), 45))); if (i < titles.length - 1) { ImageView line = new ImageView(getContext()); line.setBackgroundColor(Color.parseColor("#cccccc")); mPanel.addView(line, new LayoutParams(LayoutParams.MATCH_PARENT, 1)); } } } Button bt = new Button(getContext()); bt.setClickable(true); bt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); bt.setId(ActionSheet.CANCEL_BUTTON_ID); bt.setBackgroundResource(R.drawable.common_list_item_bg); bt.setText(getCancelButtonTitle()); bt.setTextColor(Color.parseColor("#1E82FF")); bt.setOnClickListener(this); ViewCompat.setElevation(bt, 0); ViewCompat.setTranslationZ(bt, 0); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, dp2px(getContext(), 45)); bt.setGravity(Gravity.CENTER); params.topMargin = dp2px(getContext(), 6); mPanel.addView(bt, params); mPanel.setBackgroundColor(Color.TRANSPARENT); int padding = dp2px(getContext(), 6); mPanel.setPadding(padding, padding, padding, padding); } private String getCancelButtonTitle() { return getArguments().getString(ARG_CANCEL_BUTTON_TITLE); } private String[] getOtherButtonTitles() { return getArguments().getStringArray(ARG_OTHER_BUTTON_TITLES); } private boolean getCancelableOnTouchOutside() { return getArguments().getBoolean(ARG_CANCELABLE_ONTOUCHOUTSIDE); } public void setActionSheetListener(ActionSheetListener listener) { mListener = listener; } @Override public void onClick(View v) { if (v.getId() == ActionSheet.BG_VIEW_ID && !getCancelableOnTouchOutside()) { return; } dismiss(); if (v.getId() != ActionSheet.CANCEL_BUTTON_ID && v.getId() != ActionSheet.BG_VIEW_ID) { if (mListener != null) { mListener.onOtherButtonClick(this, v.getId() - CANCEL_BUTTON_ID - 1); } isCancel = false; } } public static Builder createBuilder(Context context, FragmentManager fragmentManager) { return new Builder(context, fragmentManager); } private static int dp2px(Context context, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } public static class Builder { private Context mContext; private FragmentManager mFragmentManager; private String mCancelButtonTitle; private String[] mOtherButtonTitles; private String mTag = "actionSheet"; private boolean mCancelableOnTouchOutside; private ActionSheetListener mListener; public Builder(Context context, FragmentManager fragmentManager) { mContext = context; mFragmentManager = fragmentManager; } public Builder setCancelButtonTitle(String title) { mCancelButtonTitle = title; return this; } public Builder setCancelButtonTitle(int strId) { return setCancelButtonTitle(mContext.getString(strId)); } public Builder setOtherButtonTitles(String... titles) { mOtherButtonTitles = titles; return this; } public Builder setOtherButtonTitles(List<String> titles) { mOtherButtonTitles = new String[titles.size()]; for (int i = 0; i < titles.size(); i++) { mOtherButtonTitles[i] = titles.get(i); } return this; } public Builder setTag(String tag) { mTag = tag; return this; } public Builder setListener(ActionSheetListener listener) { this.mListener = listener; return this; } public Builder setCancelableOnTouchOutside(boolean cancelable) { mCancelableOnTouchOutside = cancelable; return this; } public Bundle prepareArguments() { Bundle bundle = new Bundle(); bundle.putString(ARG_CANCEL_BUTTON_TITLE, mCancelButtonTitle); bundle.putStringArray(ARG_OTHER_BUTTON_TITLES, mOtherButtonTitles); bundle.putBoolean(ARG_CANCELABLE_ONTOUCHOUTSIDE, mCancelableOnTouchOutside); return bundle; } public ActionSheet show() { ActionSheet actionSheet = (ActionSheet) Fragment.instantiate(mContext, ActionSheet.class.getName(), prepareArguments()); actionSheet.setActionSheetListener(mListener); actionSheet.show(mFragmentManager, mTag); return actionSheet; } } public interface ActionSheetListener { void onDismiss(ActionSheet actionSheet, boolean isCancel); void onOtherButtonClick(ActionSheet actionSheet, int index); } }