├── .gitignore ├── BlurPopupWindow ├── .gitignore ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── kyleduo │ │ │ └── blurpopupwindow │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── kyleduo │ │ │ │ └── blurpopupwindow │ │ │ │ ├── BottomMenu.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── ShadowContainer.java │ │ │ │ └── SharePopup.java │ │ └── res │ │ │ ├── drawable-xxhdpi │ │ │ ├── doctor_app_shot.png │ │ │ ├── facebook.png │ │ │ ├── google_plus.png │ │ │ ├── twitter.png │ │ │ ├── wechat.png │ │ │ └── weibo.png │ │ │ ├── drawable │ │ │ ├── dialog_button_bg.xml │ │ │ ├── menu_item_bg_selector.xml │ │ │ └── shadow.xml │ │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ ├── item_entrance.xml │ │ │ ├── layout_bottom_menu.xml │ │ │ ├── layout_bottom_popup.xml │ │ │ └── layout_dialog_like.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values-v19 │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── attrs_shadow_container.xml │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── kyleduo │ │ └── blurpopupwindow │ │ └── ExampleUnitTest.java ├── blurpopupwindow │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── kyleduo │ │ │ └── blurpopupwindow │ │ │ └── library │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── kyleduo │ │ │ │ └── blurpopupwindow │ │ │ │ └── library │ │ │ │ ├── BlurPopupWindow.java │ │ │ │ └── BlurUtils.java │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── kyleduo │ │ └── blurpopupwindow │ │ └── library │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── LICENSE ├── README.md └── preview └── preview.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | 39 | # Keystore files 40 | *.jks 41 | -------------------------------------------------------------------------------- /BlurPopupWindow/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | /.idea/ 11 | /.gradle/ 12 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.kyleduo.blurpopupwindow" 8 | minSdkVersion 14 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | 14 | renderscriptTargetApi 25 15 | renderscriptSupportModeEnabled true 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | compile project(':blurpopupwindow') 28 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 29 | exclude group: 'com.android.support', module: 'support-annotations' 30 | }) 31 | //noinspection GradleCompatible 32 | compile 'com.android.support:appcompat-v7:25.3.0' 33 | compile 'com.android.support:recyclerview-v7:25.3.0' 34 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 35 | testCompile 'junit:junit:4.12' 36 | } 37 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/kyle/Documents/developer/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/androidTest/java/com/kyleduo/blurpopupwindow/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.blurpopupwindow; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.kyleduo.blurpopupwindow", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/java/com/kyleduo/blurpopupwindow/BottomMenu.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.blurpopupwindow; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.content.Context; 5 | import android.support.annotation.NonNull; 6 | import android.view.Gravity; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.view.ViewTreeObserver; 11 | 12 | import com.kyleduo.blurpopupwindow.library.BlurPopupWindow; 13 | 14 | /** 15 | * Created by kyle on 2017/3/14. 16 | */ 17 | 18 | public class BottomMenu extends BlurPopupWindow { 19 | private static final String TAG = "IOSMenu"; 20 | 21 | public BottomMenu(@NonNull Context context) { 22 | super(context); 23 | } 24 | 25 | @Override 26 | protected View createContentView(ViewGroup parent) { 27 | View menu = LayoutInflater.from(getContext()).inflate(R.layout.layout_bottom_menu, parent, false); 28 | LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 29 | lp.gravity = Gravity.BOTTOM; 30 | menu.setLayoutParams(lp); 31 | menu.setVisibility(INVISIBLE); 32 | 33 | menu.findViewById(R.id.cancel_action).setOnClickListener(new OnClickListener() { 34 | @Override 35 | public void onClick(View v) { 36 | dismiss(); 37 | } 38 | }); 39 | return menu; 40 | } 41 | 42 | @Override 43 | protected void onShow() { 44 | super.onShow(); 45 | getContentView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 46 | @Override 47 | public void onGlobalLayout() { 48 | getViewTreeObserver().removeGlobalOnLayoutListener(this); 49 | 50 | getContentView().setVisibility(VISIBLE); 51 | int height = getContentView().getMeasuredHeight(); 52 | ObjectAnimator.ofFloat(getContentView(), "translationY", height, 0).setDuration(getAnimationDuration()).start(); 53 | } 54 | }); 55 | } 56 | 57 | @Override 58 | protected ObjectAnimator createDismissAnimator() { 59 | int height = getContentView().getMeasuredHeight(); 60 | return ObjectAnimator.ofFloat(getContentView(), "translationY", 0, height).setDuration(getAnimationDuration()); 61 | } 62 | 63 | @Override 64 | protected ObjectAnimator createShowAnimator() { 65 | return null; 66 | } 67 | 68 | public static class Builder extends BlurPopupWindow.Builder { 69 | public Builder(Context context) { 70 | super(context); 71 | this.setBlurRadius(0).setTintColor(0x70000000); 72 | } 73 | 74 | @Override 75 | protected BottomMenu createPopupWindow() { 76 | return new BottomMenu(mContext); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/java/com/kyleduo/blurpopupwindow/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.blurpopupwindow; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.support.v7.widget.Toolbar; 8 | import android.view.Gravity; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.TextView; 13 | import android.widget.Toast; 14 | 15 | import com.kyleduo.blurpopupwindow.library.BlurPopupWindow; 16 | 17 | import static com.kyleduo.blurpopupwindow.R.id.container; 18 | 19 | public class MainActivity extends AppCompatActivity { 20 | 21 | private static int[][] sPalettes = new int[][]{ 22 | {0xFFF98989, 0xFFE03535}, 23 | {0xFFC1E480, 0xFF67CC34}, 24 | {0xFFEDF179, 0xFFFFB314}, 25 | {0xFF80DDE4, 0xFF286EDC}, 26 | {0xFFE480C6, 0xFFDC285E}, 27 | }; 28 | 29 | private static String[] sTitle = new String[]{ 30 | "Bottom Menu", 31 | "Share Popup", 32 | "Dialog like" 33 | }; 34 | 35 | BottomMenu menu; 36 | 37 | @Override 38 | protected void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | setContentView(R.layout.activity_main); 41 | 42 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 43 | setSupportActionBar(toolbar); 44 | 45 | RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view); 46 | rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); 47 | EntranceAdapter adapter = new EntranceAdapter(); 48 | adapter.setOnItemClickListener(new EntranceAdapter.OnItemClickListener() { 49 | @Override 50 | public void onItemClicked(int index) { 51 | int pos = index % sTitle.length; 52 | 53 | switch (pos) { 54 | case 0: 55 | if (menu == null) { 56 | menu = new BottomMenu.Builder(MainActivity.this).setBlurRadius(2).build(); 57 | } 58 | menu.show(); 59 | break; 60 | case 1: 61 | new SharePopup.Builder(MainActivity.this).build().show(); 62 | break; 63 | case 2: 64 | new BlurPopupWindow.Builder(MainActivity.this) 65 | .setContentView(R.layout.layout_dialog_like) 66 | .bindClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | Toast.makeText(v.getContext(), "Click Button", Toast.LENGTH_SHORT).show(); 70 | } 71 | }, R.id.dialog_like_bt) 72 | .setGravity(Gravity.CENTER) 73 | .setScaleRatio(0.2f) 74 | .setBlurRadius(10) 75 | .setTintColor(0x30000000) 76 | .build() 77 | .show(); 78 | break; 79 | } 80 | } 81 | }); 82 | rv.setAdapter(adapter); 83 | 84 | } 85 | 86 | private static class EntranceViewHolder extends RecyclerView.ViewHolder { 87 | ShadowContainer shadowContainer; 88 | TextView nameTv; 89 | 90 | public EntranceViewHolder(View itemView, final EntranceAdapter.OnItemClickListener listener) { 91 | super(itemView); 92 | shadowContainer = (ShadowContainer) itemView.findViewById(container); 93 | nameTv = (TextView) itemView.findViewById(R.id.entrance_name_tv); 94 | itemView.setOnClickListener(new View.OnClickListener() { 95 | @Override 96 | public void onClick(View v) { 97 | if (listener != null) { 98 | listener.onItemClicked(getAdapterPosition()); 99 | } 100 | } 101 | }); 102 | } 103 | } 104 | 105 | private static class EntranceAdapter extends RecyclerView.Adapter { 106 | 107 | interface OnItemClickListener { 108 | void onItemClicked(int index); 109 | } 110 | 111 | private OnItemClickListener mOnItemClickListener; 112 | 113 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) { 114 | mOnItemClickListener = onItemClickListener; 115 | } 116 | 117 | @Override 118 | public EntranceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 119 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_entrance, parent, false); 120 | return new EntranceViewHolder(view, mOnItemClickListener); 121 | } 122 | 123 | @Override 124 | public void onBindViewHolder(EntranceViewHolder holder, int position) { 125 | holder.shadowContainer.setShadowColor(sPalettes[position][1]); 126 | holder.shadowContainer.setShadowRadius((int) (holder.shadowContainer.getResources().getDisplayMetrics().density * 6)); 127 | 128 | ShadowContainer.ShadowDrawable shadowDrawable = holder.shadowContainer.getShadowDrawable(); 129 | shadowDrawable.setCornerRadius((int) (holder.shadowContainer.getResources().getDisplayMetrics().density * 4)); 130 | shadowDrawable.setColors(sPalettes[position]); 131 | 132 | holder.nameTv.setText(sTitle[position % sTitle.length]); 133 | } 134 | 135 | @Override 136 | public int getItemCount() { 137 | return sPalettes.length; 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/java/com/kyleduo/blurpopupwindow/ShadowContainer.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.blurpopupwindow; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.ColorFilter; 7 | import android.graphics.LinearGradient; 8 | import android.graphics.Paint; 9 | import android.graphics.PixelFormat; 10 | import android.graphics.RectF; 11 | import android.graphics.Shader; 12 | import android.graphics.drawable.Drawable; 13 | import android.support.annotation.ColorInt; 14 | import android.support.annotation.IntRange; 15 | import android.support.annotation.NonNull; 16 | import android.support.annotation.Nullable; 17 | import android.support.annotation.Px; 18 | import android.util.AttributeSet; 19 | import android.widget.LinearLayout; 20 | 21 | /** 22 | * Created by kyle on 2017/3/23. 23 | */ 24 | 25 | public class ShadowContainer extends LinearLayout { 26 | public static final int DEFAULT_SHADOW_COLOR = 0x20000000; 27 | public static final int DEFAULT_SHADOW_RADIUS_DP = 8; 28 | 29 | private int mShadowRadius; 30 | private int mShadowColor; 31 | private ShadowDrawable mShadowDrawable; 32 | private float mDensity; 33 | 34 | public ShadowContainer(Context context) { 35 | this(context, null); 36 | } 37 | 38 | public ShadowContainer(Context context, @Nullable AttributeSet attrs) { 39 | this(context, attrs, 0); 40 | } 41 | 42 | public ShadowContainer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 43 | super(context, attrs, defStyleAttr); 44 | init(attrs); 45 | } 46 | 47 | protected void init(AttributeSet attrs) { 48 | setLayerType(LAYER_TYPE_SOFTWARE, null); 49 | 50 | mDensity = getResources().getDisplayMetrics().density; 51 | 52 | mShadowRadius = dp2px(DEFAULT_SHADOW_RADIUS_DP); 53 | mShadowColor = 0xE0BFCDE6; 54 | 55 | if (attrs != null) { 56 | TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.ShadowContainer); 57 | mShadowColor = ta.getColor(R.styleable.ShadowContainer_sc_shadowColor, mShadowColor); 58 | ta.recycle(); 59 | } 60 | 61 | mShadowDrawable = new ShadowDrawable(mDensity); 62 | mShadowDrawable.setShadow(mShadowRadius, mShadowColor); 63 | mShadowDrawable.setInset(mShadowRadius, mShadowRadius); 64 | super.setBackgroundDrawable(mShadowDrawable); 65 | 66 | setPadding( 67 | getPaddingLeft(), 68 | getPaddingTop(), 69 | getPaddingRight(), 70 | getPaddingBottom()); 71 | } 72 | 73 | private int dp2px(float dp) { 74 | return (int) (mDensity * dp); 75 | } 76 | 77 | @Override 78 | public void setBackgroundColor(@ColorInt int color) { 79 | mShadowDrawable.setBackgroundColor(color); 80 | } 81 | 82 | @Override 83 | public void setBackgroundDrawable(Drawable background) { 84 | // do nothing 85 | } 86 | 87 | public ShadowDrawable getShadowDrawable() { 88 | return mShadowDrawable; 89 | } 90 | 91 | @Override 92 | public void setPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) { 93 | left += mShadowRadius; 94 | top += mShadowRadius; 95 | right += mShadowRadius; 96 | bottom += mShadowRadius; 97 | super.setPadding(left, top, right, bottom); 98 | } 99 | 100 | public void setShadowRadius(int shadowRadius) { 101 | int pl = getPaddingLeft() - mShadowRadius; 102 | int pt = getPaddingTop() - mShadowRadius; 103 | int pr = getPaddingRight() - mShadowRadius; 104 | int pb = getPaddingBottom() - mShadowRadius; 105 | mShadowRadius = shadowRadius; 106 | mShadowDrawable.setShadow(mShadowRadius, mShadowColor); 107 | mShadowDrawable.setInset(mShadowRadius, mShadowRadius); 108 | setPadding(pl, pt, pr, pb); 109 | } 110 | 111 | public void setShadowColor(int shadowColor) { 112 | mShadowColor = shadowColor; 113 | mShadowDrawable.setShadow(mShadowRadius, mShadowColor); 114 | invalidate(); 115 | } 116 | 117 | @Override 118 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 119 | if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) { 120 | widthMeasureSpec = MeasureSpec.makeMeasureSpec( 121 | (int) Math.min(MeasureSpec.getSize(widthMeasureSpec), getResources().getDisplayMetrics().widthPixels * 0.8f), 122 | MeasureSpec.AT_MOST 123 | ); 124 | } 125 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 126 | } 127 | 128 | public static class ShadowDrawable extends Drawable { 129 | private Paint mPaint; 130 | private RectF mRectF; 131 | private int mBackgroundColor; 132 | private int mInsetX, mInsetY; 133 | private float mDensity; 134 | private int[] mBackgroundColors; 135 | private int mCornerRadius; 136 | private LinearGradient mLinearGradient; 137 | 138 | public ShadowDrawable(float density) { 139 | mDensity = density; 140 | mBackgroundColor = 0xFFFFFFFF; 141 | 142 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 143 | mRectF = new RectF(); 144 | 145 | mPaint.setColor(mBackgroundColor); 146 | mPaint.setStyle(Paint.Style.FILL); 147 | 148 | mCornerRadius = dp2px(6); 149 | } 150 | 151 | public void setInset(int insetX, int insetY) { 152 | mInsetX = insetX; 153 | mInsetY = insetY; 154 | } 155 | 156 | private int dp2px(float dp) { 157 | return (int) (mDensity * dp); 158 | } 159 | 160 | 161 | @Override 162 | public void draw(@NonNull Canvas canvas) { 163 | mRectF.set(getBounds()); 164 | mRectF.inset(mInsetX, mInsetY); 165 | 166 | if (mBackgroundColors != null) { 167 | mLinearGradient = new LinearGradient(mRectF.left, mRectF.top, mRectF.right, mRectF.bottom, mBackgroundColors, new float[]{0, 1.f}, Shader.TileMode.CLAMP); 168 | mPaint.setShader(mLinearGradient); 169 | } 170 | 171 | canvas.drawRoundRect(mRectF, mCornerRadius, mCornerRadius, mPaint); 172 | } 173 | 174 | @Override 175 | public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { 176 | mPaint.setAlpha(alpha); 177 | } 178 | 179 | @Override 180 | public void setColorFilter(@Nullable ColorFilter colorFilter) { 181 | mPaint.setColorFilter(colorFilter); 182 | } 183 | 184 | @Override 185 | public int getOpacity() { 186 | return PixelFormat.TRANSLUCENT; 187 | } 188 | 189 | public void setShadow(int radius, int color) { 190 | mPaint.setShadowLayer(radius, 0, 0, color); 191 | invalidateSelf(); 192 | } 193 | 194 | public void setBackgroundColor(int backgroundColor) { 195 | mBackgroundColor = backgroundColor; 196 | invalidateSelf(); 197 | } 198 | 199 | public LinearGradient getLinearGradient() { 200 | return mLinearGradient; 201 | } 202 | 203 | public void setColors(int[] colors) { 204 | mBackgroundColors = colors; 205 | invalidateSelf(); 206 | } 207 | 208 | public void setCornerRadius(int cornerRadius) { 209 | mCornerRadius = cornerRadius; 210 | invalidateSelf(); 211 | } 212 | } 213 | 214 | } 215 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/java/com/kyleduo/blurpopupwindow/SharePopup.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.blurpopupwindow; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.content.Context; 5 | import android.support.annotation.NonNull; 6 | import android.view.Gravity; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.view.ViewTreeObserver; 11 | 12 | import com.kyleduo.blurpopupwindow.library.BlurPopupWindow; 13 | 14 | /** 15 | * Created by kyle on 2017/3/25. 16 | */ 17 | 18 | public class SharePopup extends BlurPopupWindow { 19 | 20 | public SharePopup(@NonNull Context context) { 21 | super(context); 22 | } 23 | 24 | @Override 25 | protected View createContentView(ViewGroup parent) { 26 | View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_bottom_popup, parent, false); 27 | LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 28 | lp.gravity = Gravity.BOTTOM; 29 | view.setLayoutParams(lp); 30 | view.setVisibility(INVISIBLE); 31 | return view; 32 | } 33 | 34 | @Override 35 | protected void onShow() { 36 | super.onShow(); 37 | getContentView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 38 | @Override 39 | public void onGlobalLayout() { 40 | getViewTreeObserver().removeGlobalOnLayoutListener(this); 41 | 42 | getContentView().setVisibility(VISIBLE); 43 | int height = getContentView().getMeasuredHeight(); 44 | ObjectAnimator.ofFloat(getContentView(), "translationY", height, 0).setDuration(getAnimationDuration()).start(); 45 | } 46 | }); 47 | } 48 | 49 | @Override 50 | protected ObjectAnimator createDismissAnimator() { 51 | int height = getContentView().getMeasuredHeight(); 52 | return ObjectAnimator.ofFloat(getContentView(), "translationY", 0, height).setDuration(getAnimationDuration()); 53 | } 54 | 55 | @Override 56 | protected ObjectAnimator createShowAnimator() { 57 | return null; 58 | } 59 | 60 | public static class Builder extends BlurPopupWindow.Builder { 61 | public Builder(Context context) { 62 | super(context); 63 | this.setScaleRatio(0.25f).setBlurRadius(8).setTintColor(0x30000000); 64 | } 65 | 66 | @Override 67 | protected SharePopup createPopupWindow() { 68 | return new SharePopup(mContext); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable-xxhdpi/doctor_app_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleduo/BlurPopupWindow/7bb2f97d9acd5ae96ddacbb1701dc1646d516236/BlurPopupWindow/app/src/main/res/drawable-xxhdpi/doctor_app_shot.png -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable-xxhdpi/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleduo/BlurPopupWindow/7bb2f97d9acd5ae96ddacbb1701dc1646d516236/BlurPopupWindow/app/src/main/res/drawable-xxhdpi/facebook.png -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable-xxhdpi/google_plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleduo/BlurPopupWindow/7bb2f97d9acd5ae96ddacbb1701dc1646d516236/BlurPopupWindow/app/src/main/res/drawable-xxhdpi/google_plus.png -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable-xxhdpi/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleduo/BlurPopupWindow/7bb2f97d9acd5ae96ddacbb1701dc1646d516236/BlurPopupWindow/app/src/main/res/drawable-xxhdpi/twitter.png -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable-xxhdpi/wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleduo/BlurPopupWindow/7bb2f97d9acd5ae96ddacbb1701dc1646d516236/BlurPopupWindow/app/src/main/res/drawable-xxhdpi/wechat.png -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable-xxhdpi/weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleduo/BlurPopupWindow/7bb2f97d9acd5ae96ddacbb1701dc1646d516236/BlurPopupWindow/app/src/main/res/drawable-xxhdpi/weibo.png -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable/dialog_button_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable/menu_item_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/drawable/shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 20 | 21 | 25 | 26 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/layout/item_entrance.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 23 | 24 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/layout/layout_bottom_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 21 | 22 | 29 | 30 | 35 | 36 | 44 | 45 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/layout/layout_bottom_popup.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 18 | 19 | 29 | 30 | 38 | 39 | 42 | 43 | 46 | 47 | 48 | 51 | 52 | 55 | 56 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /BlurPopupWindow/app/src/main/res/layout/layout_dialog_like.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | 21 | 22 | 30 | 31 | 39 | 40 |