├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ ├── app-release.apk │ └── output.json └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── lxj │ │ └── xpopupdemo │ │ ├── DemoActivity.java │ │ ├── MainActivity.java │ │ ├── PageInfo.java │ │ ├── XPopupApp.java │ │ ├── custom │ │ ├── CustomAttachPopup.java │ │ ├── CustomAttachPopup2.java │ │ ├── CustomDrawerPopupView.java │ │ ├── CustomEditTextBottomPopup.java │ │ ├── CustomFullScreenPopup.java │ │ ├── CustomPartShadowPopupView.java │ │ ├── ListDrawerPopupView.java │ │ └── ZhihuCommentPopup.java │ │ └── fragment │ │ ├── AllAnimatorDemo.java │ │ ├── BaseFragment.java │ │ ├── CustomAnimatorDemo.java │ │ ├── CustomPopupDemo.java │ │ ├── ImageViewerDemo.java │ │ ├── PartShadowDemo.java │ │ └── QuickStartDemo.java │ └── res │ ├── drawable │ ├── bg_circle.xml │ ├── bg_round.xml │ └── ic_launcher_background.xml │ ├── layout │ ├── activity_demo.xml │ ├── activity_main.xml │ ├── adapter_custom_fullscreen_popup.xml │ ├── adapter_image.xml │ ├── adapter_zhihu_comment.xml │ ├── custom_attach_popup.xml │ ├── custom_attach_popup2.xml │ ├── custom_base_popup_view.xml │ ├── custom_bottom_popup.xml │ ├── custom_drawer_popup.xml │ ├── custom_edittext_bottom_popup.xml │ ├── custom_fullscreen_popup.xml │ ├── custom_list_drawer.xml │ ├── custom_part_shadow_popup.xml │ ├── custom_popup.xml │ ├── custom_popup2.xml │ ├── customxxx.xml │ ├── fragment_all_animator_demo.xml │ ├── fragment_custom_animator_demo.xml │ ├── fragment_image_preview.xml │ ├── fragment_part_shadow_demo.xml │ └── fragment_quickstart.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 │ ├── arrow.png │ ├── dropdown.png │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── lxj │ │ └── xpopup │ │ ├── XPopup.java │ │ ├── animator │ │ ├── PopupAnimator.java │ │ ├── ScaleAlphaAnimator.java │ │ ├── ScrollScaleAnimator.java │ │ ├── ShadowBgAnimator.java │ │ ├── TranslateAlphaAnimator.java │ │ └── TranslateAnimator.java │ │ ├── core │ │ ├── AttachPopupView.java │ │ ├── BasePopupView.java │ │ ├── BottomPopupView.java │ │ ├── CenterPopupView.java │ │ ├── DrawerPopupView.java │ │ ├── HorizontalAttachPopupView.java │ │ ├── ImageViewerPopupView.java │ │ └── PopupInfo.java │ │ ├── enums │ │ ├── ImageType.java │ │ ├── LayoutStatus.java │ │ ├── PopupAnimation.java │ │ ├── PopupPosition.java │ │ ├── PopupStatus.java │ │ └── PopupType.java │ │ ├── impl │ │ ├── AttachListPopupView.java │ │ ├── BottomListPopupView.java │ │ ├── CenterListPopupView.java │ │ ├── ConfirmPopupView.java │ │ ├── FullScreenPopupView.java │ │ ├── InputConfirmPopupView.java │ │ ├── LoadingPopupView.java │ │ └── PartShadowPopupView.java │ │ ├── interfaces │ │ ├── OnCancelListener.java │ │ ├── OnClickOutsideListener.java │ │ ├── OnConfirmListener.java │ │ ├── OnDragChangeListener.java │ │ ├── OnInputConfirmListener.java │ │ ├── OnSelectListener.java │ │ ├── OnSrcViewUpdateListener.java │ │ ├── XPopupCallback.java │ │ └── XPopupImageLoader.java │ │ ├── photoview │ │ ├── Compat.java │ │ ├── CustomGestureDetector.java │ │ ├── OnGestureListener.java │ │ ├── OnMatrixChangedListener.java │ │ ├── OnOutsidePhotoTapListener.java │ │ ├── OnPhotoTapListener.java │ │ ├── OnScaleChangedListener.java │ │ ├── OnSingleFlingListener.java │ │ ├── OnViewDragListener.java │ │ ├── OnViewTapListener.java │ │ ├── PhotoView.java │ │ ├── PhotoViewAttacher.java │ │ └── Util.java │ │ ├── util │ │ ├── ImageHeaderParser.java │ │ ├── KeyboardUtils.java │ │ └── XPopupUtils.java │ │ └── widget │ │ ├── BlankView.java │ │ ├── CheckView.java │ │ ├── HackyViewPager.java │ │ ├── LoadingView.java │ │ ├── PartShadowContainer.java │ │ ├── PhotoViewContainer.java │ │ ├── PopupDrawerLayout.java │ │ ├── SmartDragLayout.java │ │ └── VerticalRecyclerView.java │ └── res │ ├── drawable │ ├── _xpopup_round3_bg.xml │ ├── _xpopup_round3_dark_bg.xml │ └── _xpopup_shadow.9.png │ ├── layout │ ├── _xpopup_adapter_text.xml │ ├── _xpopup_attach_impl_list.xml │ ├── _xpopup_attach_popup_view.xml │ ├── _xpopup_bottom_popup_view.xml │ ├── _xpopup_center_impl_confirm.xml │ ├── _xpopup_center_impl_list.xml │ ├── _xpopup_center_impl_loading.xml │ ├── _xpopup_center_popup_view.xml │ ├── _xpopup_divider.xml │ ├── _xpopup_drawer_popup_view.xml │ ├── _xpopup_image_viewer_popup_view.xml │ └── _xpopup_part_shadow_popup_view.xml │ └── values │ ├── colors.xml │ └── styles.xml ├── screenshot ├── bottom_edit.gif ├── comment_edit.gif ├── download.png ├── fullscreen.gif ├── horizontal_attach.gif ├── image_viewer1.gif ├── image_viewer2.gif ├── image_viewer3.gif ├── logo.png ├── preview.gif ├── preview2.gif ├── preview3.gif ├── preview4.gif ├── preview_attach.gif ├── preview_bottom.gif ├── preview_drawer.gif ├── preview_part.gif └── qqgroup.png ├── settings.gradle └── xpopup.jks /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | bintray.sh 10 | bintray.bat -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.lxj.xpopupdemo" 7 | minSdkVersion 16 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | } 12 | buildTypes { 13 | release { 14 | shrinkResources true 15 | minifyEnabled true 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(include: ['*.jar'], dir: 'libs') 24 | implementation 'com.android.support:appcompat-v7:28.0.0' 25 | implementation 'com.android.support:recyclerview-v7:28.0.0' 26 | implementation 'com.android.support:design:28.0.0' 27 | implementation 'com.lxj:easyadapter:1.1.0' 28 | implementation 'com.github.bumptech.glide:glide:4.8.0' 29 | implementation project(':library') 30 | implementation 'com.blankj:utilcode:1.23.6' 31 | implementation 'com.squareup.leakcanary:leakcanary-android:1.6.2' 32 | implementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.2' 33 | implementation 'com.android.support:cardview-v7:28.0.0' 34 | } 35 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -dontwarn com.lxj.xpopup.widget.** 23 | -keep class com.lxj.xpopup.widget.**{*;} -------------------------------------------------------------------------------- /app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/DemoActivity.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.text.Editable; 7 | import android.text.TextWatcher; 8 | import android.view.View; 9 | import android.widget.EditText; 10 | import android.widget.Toast; 11 | 12 | import com.lxj.xpopup.XPopup; 13 | import com.lxj.xpopup.core.BasePopupView; 14 | import com.lxj.xpopup.enums.PopupAnimation; 15 | import com.lxj.xpopup.enums.PopupPosition; 16 | import com.lxj.xpopup.interfaces.OnConfirmListener; 17 | import com.lxj.xpopup.interfaces.OnSelectListener; 18 | 19 | /** 20 | * Description: 21 | * Create by lxj, at 2019/2/2 22 | */ 23 | public class DemoActivity extends AppCompatActivity { 24 | EditText editText; 25 | @Override 26 | protected void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_demo); 29 | editText = findViewById(R.id.et); 30 | findViewById(R.id.text).setOnClickListener(new View.OnClickListener() { 31 | @Override 32 | public void onClick(View v) { 33 | showMultiPopup(); 34 | } 35 | }); 36 | showMultiPopup(); 37 | 38 | final BasePopupView popupView = new XPopup.Builder(this) 39 | .atView(editText) 40 | .isRequestFocus(false) 41 | .hasShadowBg(false) 42 | .popupAnimation(PopupAnimation.ScaleAlphaFromCenter) 43 | .asAttachList(new String[]{"联想到的内容 - 1", "联想到的内容 - 2", "联想到的内容 - 333"}, null, new OnSelectListener() { 44 | @Override 45 | public void onSelect(int position, String text) { 46 | Toast.makeText(DemoActivity.this, text, Toast.LENGTH_LONG).show(); 47 | } 48 | }); 49 | editText.addTextChangedListener(new TextWatcher() { 50 | @Override 51 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { } 52 | @Override 53 | public void onTextChanged(CharSequence s, int start, int before, int count) { } 54 | @Override 55 | public void afterTextChanged(Editable s) { 56 | if(s.toString().isEmpty()){ 57 | popupView.dismiss(); 58 | return; 59 | } 60 | if(popupView.isDismiss()){ 61 | popupView.show(); 62 | } 63 | } 64 | }); 65 | } 66 | 67 | public void showMultiPopup(){ 68 | final BasePopupView loadingPopup = new XPopup.Builder(this).asLoading(); 69 | loadingPopup.show(); 70 | new XPopup.Builder(DemoActivity.this) 71 | .autoDismiss(false) 72 | .asBottomList("haha", new String[]{"点我显示弹窗", "点我显示弹窗", "点我显示弹窗", "点我显示弹窗"}, new OnSelectListener() { 73 | @Override 74 | public void onSelect(int position, String text) { 75 | Toast.makeText(DemoActivity.this, text, Toast.LENGTH_LONG).show(); 76 | 77 | new XPopup.Builder(DemoActivity.this).asConfirm("测试", "aaaa", new OnConfirmListener() { 78 | @Override 79 | public void onConfirm() { 80 | loadingPopup.dismiss(); 81 | } 82 | }).show(); 83 | } 84 | }).show(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.design.widget.TabLayout; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v4.app.FragmentManager; 9 | import android.support.v4.app.FragmentPagerAdapter; 10 | import android.support.v4.view.ViewPager; 11 | import android.support.v7.app.AppCompatActivity; 12 | 13 | import com.lxj.xpopup.XPopup; 14 | import com.lxj.xpopupdemo.fragment.AllAnimatorDemo; 15 | import com.lxj.xpopupdemo.fragment.BaseFragment; 16 | import com.lxj.xpopupdemo.fragment.CustomAnimatorDemo; 17 | import com.lxj.xpopupdemo.fragment.CustomPopupDemo; 18 | import com.lxj.xpopupdemo.fragment.ImageViewerDemo; 19 | import com.lxj.xpopupdemo.fragment.PartShadowDemo; 20 | import com.lxj.xpopupdemo.fragment.QuickStartDemo; 21 | 22 | public class MainActivity extends AppCompatActivity { 23 | 24 | PageInfo[] pageInfos = new PageInfo[]{ 25 | new PageInfo("快速开始", new QuickStartDemo()), 26 | new PageInfo("局部阴影", new PartShadowDemo()), 27 | new PageInfo("图片浏览", new ImageViewerDemo()), 28 | new PageInfo("尝试不同动画", new AllAnimatorDemo()), 29 | new PageInfo("自定义弹窗", new CustomPopupDemo()), 30 | new PageInfo("自定义动画", new CustomAnimatorDemo()) 31 | }; 32 | 33 | TabLayout tabLayout; 34 | ViewPager viewPager; 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_main); 39 | tabLayout = findViewById(R.id.tabLayout); 40 | viewPager = findViewById(R.id.viewPager); 41 | 42 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 43 | @Override 44 | public void onPageScrolled(int i, float v, int i1) { 45 | } 46 | @Override 47 | public void onPageSelected(int i) { 48 | callFragmentInit(i); 49 | } 50 | @Override 51 | public void onPageScrollStateChanged(int i) { 52 | 53 | } 54 | }); 55 | 56 | viewPager.setAdapter(new MainAdapter(getSupportFragmentManager())); 57 | tabLayout.setupWithViewPager(viewPager); 58 | 59 | viewPager.postDelayed(new Runnable() { 60 | @Override 61 | public void run() { 62 | callFragmentInit(0); 63 | } 64 | },300); 65 | 66 | XPopup.setPrimaryColor(getResources().getColor(R.color.colorPrimary)); 67 | // XPopup.setAnimationDuration(1000); 68 | // XPopup.setPrimaryColor(Color.RED); 69 | } 70 | 71 | private void callFragmentInit(int i){ 72 | BaseFragment fragment = (BaseFragment) ((FragmentPagerAdapter) viewPager.getAdapter()).getItem(i); 73 | fragment.init(fragment.getView()); 74 | } 75 | 76 | class MainAdapter extends FragmentPagerAdapter{ 77 | 78 | public MainAdapter(FragmentManager fm) { 79 | super(fm); 80 | } 81 | 82 | @Override 83 | public Fragment getItem(int i) { 84 | return pageInfos[i].fragment; 85 | } 86 | 87 | @Override 88 | public int getCount() { 89 | return pageInfos.length; 90 | } 91 | 92 | @Nullable 93 | @Override 94 | public CharSequence getPageTitle(int position) { 95 | return pageInfos[position].title; 96 | } 97 | } 98 | 99 | @Override 100 | protected void onDestroy() { 101 | super.onDestroy(); 102 | viewPager.removeAllViews(); 103 | viewPager = null; 104 | pageInfos = null; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/PageInfo.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | /** 6 | * Description: 7 | * Create by dance, at 2018/12/9 8 | */ 9 | public class PageInfo { 10 | public String title; 11 | public Fragment fragment; 12 | 13 | public PageInfo(String title, Fragment fragment) { 14 | this.title = title; 15 | this.fragment = fragment; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/XPopupApp.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo; 2 | 3 | import android.app.Application; 4 | import com.squareup.leakcanary.LeakCanary; 5 | 6 | /** 7 | * Description: 8 | * Create by dance, at 2019/1/1 9 | */ 10 | public class XPopupApp extends Application { 11 | @Override 12 | public void onCreate() { 13 | super.onCreate(); 14 | // if (LeakCanary.isInAnalyzerProcess(this)) { 15 | // return; 16 | // } 17 | // LeakCanary.install(this); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/CustomAttachPopup.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.view.View; 6 | 7 | import com.blankj.utilcode.util.ToastUtils; 8 | import com.lxj.xpopup.core.HorizontalAttachPopupView; 9 | import com.lxj.xpopupdemo.R; 10 | 11 | /** 12 | * Description: 13 | * Create by lxj, at 2019/3/13 14 | */ 15 | public class CustomAttachPopup extends HorizontalAttachPopupView { 16 | public CustomAttachPopup(@NonNull Context context) { 17 | super(context); 18 | } 19 | 20 | @Override 21 | protected int getImplLayoutId() { 22 | return R.layout.custom_attach_popup; 23 | } 24 | 25 | @Override 26 | protected void onCreate() { 27 | super.onCreate(); 28 | findViewById(R.id.tv_zan).setOnClickListener(new OnClickListener() { 29 | @Override 30 | public void onClick(View v) { 31 | ToastUtils.showShort("赞"); 32 | } 33 | }); 34 | findViewById(R.id.tv_comment).setOnClickListener(new OnClickListener() { 35 | @Override 36 | public void onClick(View v) { 37 | ToastUtils.showShort("评论"); 38 | } 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/CustomAttachPopup2.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.view.View; 6 | 7 | import com.blankj.utilcode.util.ToastUtils; 8 | import com.lxj.xpopup.core.AttachPopupView; 9 | import com.lxj.xpopup.core.HorizontalAttachPopupView; 10 | import com.lxj.xpopupdemo.R; 11 | 12 | /** 13 | * Description: 14 | * Create by lxj, at 2019/3/13 15 | */ 16 | public class CustomAttachPopup2 extends AttachPopupView { 17 | public CustomAttachPopup2(@NonNull Context context) { 18 | super(context); 19 | } 20 | 21 | @Override 22 | protected int getImplLayoutId() { 23 | return R.layout.custom_attach_popup2; 24 | } 25 | 26 | @Override 27 | protected void onCreate() { 28 | super.onCreate(); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/CustomDrawerPopupView.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | import android.widget.Toast; 10 | 11 | import com.lxj.xpopup.core.DrawerPopupView; 12 | import com.lxj.xpopupdemo.R; 13 | 14 | import java.util.Random; 15 | 16 | /** 17 | * Description: 自定义抽屉弹窗 18 | * Create by dance, at 2018/12/20 19 | */ 20 | public class CustomDrawerPopupView extends DrawerPopupView { 21 | TextView text; 22 | public CustomDrawerPopupView(@NonNull Context context) { 23 | super(context); 24 | } 25 | @Override 26 | protected int getImplLayoutId() { 27 | return R.layout.custom_drawer_popup; 28 | } 29 | 30 | @Override 31 | protected void onCreate() { 32 | super.onCreate(); 33 | Log.e("tag", "CustomDrawerPopupView onCreate"); 34 | text = findViewById(R.id.text); 35 | findViewById(R.id.btn).setOnClickListener(new OnClickListener() { 36 | @Override 37 | public void onClick(View v) { 38 | dismiss(); 39 | } 40 | }); 41 | text.setText(new Random().nextInt()+""); 42 | 43 | //通过设置topMargin,可以让Drawer弹窗进行局部阴影展示 44 | // ViewGroup.MarginLayoutParams params = (MarginLayoutParams) getPopupContentView().getLayoutParams(); 45 | // params.topMargin = 450; 46 | } 47 | 48 | @Override 49 | protected void onShow() { 50 | super.onShow(); 51 | Log.e("tag", "CustomDrawerPopupView onShow"); 52 | } 53 | 54 | @Override 55 | protected void onDismiss() { 56 | super.onDismiss(); 57 | Log.e("tag", "CustomDrawerPopupView onDismiss"); 58 | } 59 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/CustomEditTextBottomPopup.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.EditText; 8 | 9 | import com.lxj.xpopup.core.BottomPopupView; 10 | import com.lxj.xpopup.util.XPopupUtils; 11 | import com.lxj.xpopupdemo.R; 12 | 13 | /** 14 | * Description: 带有输入框的Bottom弹窗 15 | * Create by dance, at 2019/2/27 16 | */ 17 | public class CustomEditTextBottomPopup extends BottomPopupView { 18 | public CustomEditTextBottomPopup(@NonNull Context context) { 19 | super(context); 20 | } 21 | 22 | @Override 23 | protected int getImplLayoutId() { 24 | return R.layout.custom_edittext_bottom_popup; 25 | } 26 | 27 | @Override 28 | protected void onCreate() { 29 | super.onCreate(); 30 | } 31 | 32 | @Override 33 | protected void onShow() { 34 | super.onShow(); 35 | Log.e("tag", "CustomEditTextBottomPopup onShow"); 36 | findViewById(R.id.btn_finish).setOnClickListener(new OnClickListener() { 37 | @Override 38 | public void onClick(View v) { 39 | dismiss(); 40 | } 41 | }); 42 | } 43 | 44 | @Override 45 | protected void onDismiss() { 46 | super.onDismiss(); 47 | Log.e("tag", "CustomEditTextBottomPopup onDismiss"); 48 | } 49 | 50 | public String getComment(){ 51 | EditText et = findViewById(R.id.et_comment); 52 | return et.getText().toString(); 53 | } 54 | 55 | // @Override 56 | // protected int getMaxHeight() { 57 | // return (int) (XPopupUtils.getWindowHeight(getContext())*0.75); 58 | // } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/CustomFullScreenPopup.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | import com.lxj.easyadapter.CommonAdapter; 8 | import com.lxj.easyadapter.ViewHolder; 9 | import com.lxj.xpopup.impl.FullScreenPopupView; 10 | import com.lxj.xpopupdemo.R; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * Description: 17 | * Create by lxj, at 2019/3/12 18 | */ 19 | public class CustomFullScreenPopup extends FullScreenPopupView { 20 | public CustomFullScreenPopup(@NonNull Context context) { 21 | super(context); 22 | } 23 | 24 | @Override 25 | protected int getImplLayoutId() { 26 | return R.layout.custom_fullscreen_popup; 27 | } 28 | 29 | RecyclerView recyclerView; 30 | @Override 31 | protected void onCreate() { 32 | super.onCreate(); 33 | recyclerView = findViewById(R.id.recyclerView); 34 | List data = new ArrayList<>(); 35 | for (int i = 0; i < 30; i++) { 36 | data.add("text"); 37 | } 38 | recyclerView.setAdapter(new CommonAdapter(R.layout.adapter_custom_fullscreen_popup, data) { 39 | @Override 40 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) { 41 | holder.setText(R.id.text, s + "-"+position); 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/CustomPartShadowPopupView.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import com.lxj.xpopup.impl.PartShadowPopupView; 11 | import com.lxj.xpopup.util.XPopupUtils; 12 | import com.lxj.xpopupdemo.R; 13 | 14 | /** 15 | * Description: 16 | * Create by dance, at 2018/12/21 17 | */ 18 | public class CustomPartShadowPopupView extends PartShadowPopupView { 19 | public CustomPartShadowPopupView(@NonNull Context context) { 20 | super(context); 21 | } 22 | @Override 23 | protected int getImplLayoutId() { 24 | return R.layout.custom_part_shadow_popup; 25 | } 26 | 27 | TextView text; 28 | @Override 29 | protected void onCreate() { 30 | super.onCreate(); 31 | text = findViewById(R.id.text); 32 | Log.e("tag","CustomPartShadowPopupView onCreate"); 33 | findViewById(R.id.btnClose).setOnClickListener(new OnClickListener() { 34 | @Override 35 | public void onClick(View v) { 36 | dismiss(); 37 | } 38 | }); 39 | findViewById(R.id.ch).setOnClickListener(new OnClickListener() { 40 | @Override 41 | public void onClick(View v) { 42 | text.setText(text.getText()+"\n 啦啦啦啦啦啦"); 43 | 44 | } 45 | }); 46 | } 47 | 48 | @Override 49 | protected void onShow() { 50 | super.onShow(); 51 | Log.e("tag","CustomPartShadowPopupView onShow"); 52 | } 53 | 54 | @Override 55 | protected void onDismiss() { 56 | super.onDismiss(); 57 | Log.e("tag","CustomPartShadowPopupView onDismiss"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/ListDrawerPopupView.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.View; 8 | 9 | import com.lxj.easyadapter.CommonAdapter; 10 | import com.lxj.easyadapter.MultiItemTypeAdapter; 11 | import com.lxj.easyadapter.ViewHolder; 12 | import com.lxj.xpopup.XPopup; 13 | import com.lxj.xpopup.core.DrawerPopupView; 14 | import com.lxj.xpopup.enums.PopupPosition; 15 | import com.lxj.xpopup.interfaces.OnSelectListener; 16 | import com.lxj.xpopup.widget.PopupDrawerLayout; 17 | import com.lxj.xpopupdemo.R; 18 | 19 | import java.util.ArrayList; 20 | 21 | /** 22 | * Description: 23 | * Create by dance, at 2019/1/9 24 | */ 25 | public class ListDrawerPopupView extends DrawerPopupView { 26 | RecyclerView recyclerView; 27 | public ListDrawerPopupView(@NonNull Context context) { 28 | super(context); 29 | } 30 | 31 | @Override 32 | protected int getImplLayoutId() { 33 | return R.layout.custom_list_drawer; 34 | } 35 | final ArrayList data = new ArrayList<>(); 36 | @Override 37 | protected void onCreate() { 38 | recyclerView = findViewById(R.id.recyclerView); 39 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 40 | 41 | for (int i = 0; i < 50; i++) { 42 | data.add(""+i); 43 | } 44 | 45 | final CommonAdapter commonAdapter = new CommonAdapter(android.R.layout.simple_list_item_1, data) { 46 | @Override 47 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) { 48 | holder.setText(android.R.id.text1, s); 49 | } 50 | }; 51 | 52 | recyclerView.setAdapter(commonAdapter); 53 | findViewById(R.id.btn).setOnClickListener(new OnClickListener() { 54 | @Override 55 | public void onClick(View v) { 56 | data.remove(0); 57 | commonAdapter.notifyDataSetChanged(); 58 | } 59 | }); 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/custom/ZhihuCommentPopup.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.custom; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.annotation.NonNull; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.util.Log; 8 | import android.view.View; 9 | 10 | import com.lxj.easyadapter.CommonAdapter; 11 | import com.lxj.easyadapter.MultiItemTypeAdapter; 12 | import com.lxj.easyadapter.ViewHolder; 13 | import com.lxj.xpopup.XPopup; 14 | import com.lxj.xpopup.core.BottomPopupView; 15 | import com.lxj.xpopup.interfaces.OnConfirmListener; 16 | import com.lxj.xpopup.interfaces.XPopupCallback; 17 | import com.lxj.xpopup.util.XPopupUtils; 18 | import com.lxj.xpopup.widget.VerticalRecyclerView; 19 | import com.lxj.xpopupdemo.DemoActivity; 20 | import com.lxj.xpopupdemo.R; 21 | 22 | import java.util.ArrayList; 23 | 24 | /** 25 | * Description: 仿知乎底部评论弹窗 26 | * Create by dance, at 2018/12/25 27 | */ 28 | public class ZhihuCommentPopup extends BottomPopupView { 29 | VerticalRecyclerView recyclerView; 30 | private ArrayList data; 31 | private CommonAdapter commonAdapter; 32 | 33 | public ZhihuCommentPopup(@NonNull Context context) { 34 | super(context); 35 | } 36 | @Override 37 | protected int getImplLayoutId() { 38 | return R.layout.custom_bottom_popup; 39 | } 40 | 41 | @Override 42 | protected void onCreate() { 43 | super.onCreate(); 44 | recyclerView = findViewById(R.id.recyclerView); 45 | findViewById(R.id.tv_temp).setOnClickListener(new OnClickListener() { 46 | @Override 47 | public void onClick(View v) { 48 | //弹出新的弹窗用来输入 49 | final CustomEditTextBottomPopup textBottomPopup = new CustomEditTextBottomPopup(getContext()); 50 | new XPopup.Builder(getContext()) 51 | .autoOpenSoftInput(true) 52 | // .hasShadowBg(false) 53 | .setPopupCallback(new XPopupCallback() { 54 | @Override 55 | public void onShow() { } 56 | @Override 57 | public void onDismiss() { 58 | String comment = textBottomPopup.getComment(); 59 | if(!comment.isEmpty()){ 60 | data.add(0,comment); 61 | commonAdapter.notifyDataSetChanged(); 62 | } 63 | } 64 | }) 65 | .asCustom(textBottomPopup) 66 | .show(); 67 | } 68 | }); 69 | 70 | data = new ArrayList<>(); 71 | for (int i = 0; i < 15; i++) { 72 | data.add("这是一个自定义Bottom类型的弹窗!你可以在里面添加任何滚动的View,我已经智能处理好嵌套滚动,你只需编写UI和逻辑即可!"); 73 | } 74 | commonAdapter = new CommonAdapter(R.layout.adapter_zhihu_comment, data) { 75 | @Override 76 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) { 77 | holder.setText(R.id.name, "知乎大神 - "+position) 78 | .setText(R.id.comment, s); 79 | } 80 | }; 81 | commonAdapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener(){ 82 | @Override 83 | public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) { 84 | //不要直接这样做,会导致消失动画未执行完就跳转界面,不流畅。 85 | // dismiss(); 86 | // getContext().startActivity(new Intent(getContext(), DemoActivity.class)) 87 | //可以等消失动画执行完毕再开启新界面 88 | dismissWith(new Runnable() { 89 | @Override 90 | public void run() { 91 | getContext().startActivity(new Intent(getContext(), DemoActivity.class)); 92 | } 93 | }); 94 | 95 | } 96 | }); 97 | recyclerView.setHasFixedSize(true); 98 | recyclerView.setAdapter(commonAdapter); 99 | } 100 | 101 | //完全可见执行 102 | @Override 103 | protected void onShow() { 104 | super.onShow(); 105 | } 106 | 107 | //完全消失执行 108 | @Override 109 | protected void onDismiss() { 110 | 111 | } 112 | 113 | @Override 114 | protected int getMaxHeight() { 115 | return (int) (XPopupUtils.getWindowHeight(getContext())*.85f); 116 | } 117 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/fragment/AllAnimatorDemo.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.fragment; 2 | 3 | import android.view.View; 4 | import android.widget.AdapterView; 5 | import android.widget.ArrayAdapter; 6 | import android.widget.Spinner; 7 | 8 | import com.lxj.xpopup.XPopup; 9 | import com.lxj.xpopup.enums.PopupAnimation; 10 | import com.lxj.xpopupdemo.R; 11 | 12 | /** 13 | * Description: 14 | * Create by dance, at 2018/12/9 15 | */ 16 | public class AllAnimatorDemo extends BaseFragment { 17 | Spinner spinner; 18 | @Override 19 | protected int getLayoutId() { 20 | return R.layout.fragment_all_animator_demo; 21 | } 22 | PopupAnimation[] datas; 23 | @Override 24 | public void init(View view) { 25 | spinner = view.findViewById(R.id.spinner); 26 | 27 | datas = PopupAnimation.values(); 28 | spinner.setAdapter(new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, datas)); 29 | 30 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 31 | @Override 32 | public void onItemSelected(AdapterView parent, View view, final int position, long id) { 33 | spinner.postDelayed(new Runnable() { 34 | @Override 35 | public void run() { 36 | new XPopup.Builder(getContext()) 37 | .popupAnimation(datas[position]) 38 | .asConfirm("演示应用不同的动画", "你可以为弹窗选择任意一种动画,但这并不必要,因为我已经默认给每种弹窗设定了最佳动画!对于你自定义的弹窗,可以随心选择心仪的动画方案。", null) 39 | .show(); 40 | } 41 | },200); //确保spinner的消失动画不影响XPopup动画,可以看得更清晰 42 | 43 | } 44 | @Override 45 | public void onNothingSelected(AdapterView parent) { 46 | } 47 | }); 48 | 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/fragment/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.Toast; 11 | 12 | /** 13 | * Description: 14 | * Create by dance, at 2018/12/9 15 | */ 16 | public abstract class BaseFragment extends Fragment { 17 | @Nullable 18 | @Override 19 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 20 | return inflater.inflate(getLayoutId(), container,false); 21 | } 22 | 23 | protected abstract int getLayoutId(); 24 | public abstract void init(View view); 25 | 26 | public void toast(String msg){ 27 | Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/fragment/CustomAnimatorDemo.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.fragment; 2 | 3 | import android.support.v4.view.animation.FastOutSlowInInterpolator; 4 | import android.view.View; 5 | 6 | import com.lxj.xpopup.XPopup; 7 | import com.lxj.xpopup.animator.PopupAnimator; 8 | import com.lxj.xpopupdemo.R; 9 | 10 | /** 11 | * Description: 12 | * Create by dance, at 2018/12/9 13 | */ 14 | public class CustomAnimatorDemo extends BaseFragment { 15 | 16 | @Override 17 | protected int getLayoutId() { 18 | return R.layout.fragment_custom_animator_demo; 19 | } 20 | 21 | public void init(View view) { 22 | view.findViewById(R.id.btn_show).setOnClickListener(listener); 23 | } 24 | 25 | View.OnClickListener listener = new View.OnClickListener() { 26 | @Override 27 | public void onClick(View v) { 28 | new XPopup.Builder(getContext()) 29 | .customAnimator(new RotateAnimator()) 30 | .asConfirm("演示自定义动画", "当前的动画是一个自定义的旋转动画,无论是自定义弹窗还是自定义动画,已经被设计得非常简单;这个动画代码只有6行即可完成!", null) 31 | .show(); 32 | } 33 | }; 34 | 35 | 36 | static class RotateAnimator extends PopupAnimator{ 37 | @Override 38 | public void initAnimator() { 39 | targetView.setScaleX(0); 40 | targetView.setScaleY(0); 41 | targetView.setAlpha(0); 42 | targetView.setRotation(360); 43 | } 44 | @Override 45 | public void animateShow() { 46 | targetView.animate().rotation(0).scaleX(1).scaleY(1).alpha(1).setInterpolator(new FastOutSlowInInterpolator()).setDuration(getDuration()).start(); 47 | } 48 | @Override 49 | public void animateDismiss() { 50 | targetView.animate().rotation(720).scaleX(0).scaleY(0).alpha(0).setInterpolator(new FastOutSlowInInterpolator()).setDuration(getDuration()).start(); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/fragment/CustomPopupDemo.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.fragment; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.util.Log; 8 | import android.view.View; 9 | import android.widget.AdapterView; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.Spinner; 12 | import android.widget.TextView; 13 | 14 | import com.lxj.easyadapter.CommonAdapter; 15 | import com.lxj.easyadapter.ViewHolder; 16 | import com.lxj.xpopup.XPopup; 17 | import com.lxj.xpopup.animator.PopupAnimator; 18 | import com.lxj.xpopup.core.BottomPopupView; 19 | import com.lxj.xpopup.core.CenterPopupView; 20 | import com.lxj.xpopup.enums.PopupAnimation; 21 | import com.lxj.xpopup.interfaces.XPopupCallback; 22 | import com.lxj.xpopup.util.XPopupUtils; 23 | import com.lxj.xpopupdemo.R; 24 | 25 | import java.util.ArrayList; 26 | 27 | /** 28 | * Description: 29 | * Create by dance, at 2018/12/9 30 | */ 31 | public class CustomPopupDemo extends BaseFragment { 32 | Spinner spinner; 33 | TextView temp; 34 | 35 | @Override 36 | protected int getLayoutId() { 37 | return R.layout.fragment_all_animator_demo; 38 | } 39 | 40 | PopupAnimation[] datas; 41 | 42 | @Override 43 | public void init(View view) { 44 | spinner = view.findViewById(R.id.spinner); 45 | temp = view.findViewById(R.id.temp); 46 | temp.setText("演示如何自定义弹窗,并给自定义的弹窗应用不同的内置动画方案;你也可以为自己的弹窗编写自定义的动画。"); 47 | 48 | datas = PopupAnimation.values(); 49 | spinner.setAdapter(new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, datas)); 50 | 51 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 52 | @Override 53 | public void onItemSelected(AdapterView parent, View view, final int position, long id) { 54 | spinner.postDelayed(new Runnable() { 55 | @Override 56 | public void run() { 57 | new XPopup.Builder(getContext()) 58 | .popupAnimation(datas[position]) 59 | .autoOpenSoftInput(true) 60 | .asCustom(new CustomPopup(getContext())) 61 | .show(); 62 | } 63 | }, 200); //确保spinner的消失动画不影响XPopup动画,可以看得更清晰 64 | 65 | } 66 | 67 | @Override 68 | public void onNothingSelected(AdapterView parent) { 69 | } 70 | }); 71 | 72 | } 73 | 74 | 75 | public static class CustomPopup extends CenterPopupView { 76 | public CustomPopup(@NonNull Context context) { 77 | super(context); 78 | } 79 | 80 | @Override 81 | protected int getImplLayoutId() { 82 | return R.layout.custom_popup; 83 | } 84 | 85 | @Override 86 | protected void onCreate() { 87 | super.onCreate(); 88 | findViewById(R.id.tv_close).setOnClickListener(new OnClickListener() { 89 | @Override 90 | public void onClick(View v) { 91 | dismiss(); 92 | } 93 | }); 94 | } 95 | 96 | @Override 97 | protected void onShow() { 98 | super.onShow(); 99 | } 100 | 101 | // @Override 102 | // protected int getMaxHeight() { 103 | // return 200; 104 | // } 105 | // 106 | //返回0表示让宽度撑满window,或者你可以返回一个任意宽度 107 | // @Override 108 | // protected int getMaxWidth() { 109 | // return 1200; 110 | // } 111 | } 112 | 113 | static class CustomPopup2 extends BottomPopupView { 114 | RecyclerView recyclerView; 115 | 116 | public CustomPopup2(@NonNull Context context) { 117 | super(context); 118 | } 119 | 120 | @Override 121 | protected int getImplLayoutId() { 122 | return R.layout.custom_popup2; 123 | } 124 | 125 | @Override 126 | protected void onCreate() { 127 | super.onCreate(); 128 | recyclerView = findViewById(R.id.recyclerView); 129 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 130 | ArrayList data = new ArrayList<>(); 131 | for (int i = 0; i < 3; i++) { 132 | data.add("" + i); 133 | } 134 | 135 | recyclerView.setAdapter(new CommonAdapter(android.R.layout.simple_list_item_1, data) { 136 | @Override 137 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) { 138 | holder.setText(android.R.id.text1, s); 139 | } 140 | }); 141 | } 142 | 143 | // @Override 144 | // protected int getMaxHeight() { 145 | // return 1200; 146 | // } 147 | // 148 | //返回0表示让宽度撑满window,或者你可以返回一个任意宽度 149 | // @Override 150 | // protected int getMaxWidth() { 151 | // return 1200; 152 | // } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /app/src/main/java/com/lxj/xpopupdemo/fragment/PartShadowDemo.java: -------------------------------------------------------------------------------- 1 | package com.lxj.xpopupdemo.fragment; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.Toast; 9 | 10 | import com.blankj.utilcode.util.ToastUtils; 11 | import com.lxj.easyadapter.CommonAdapter; 12 | import com.lxj.easyadapter.MultiItemTypeAdapter; 13 | import com.lxj.easyadapter.ViewHolder; 14 | import com.lxj.xpopup.XPopup; 15 | import com.lxj.xpopup.enums.PopupPosition; 16 | import com.lxj.xpopup.interfaces.OnSelectListener; 17 | import com.lxj.xpopup.interfaces.XPopupCallback; 18 | import com.lxj.xpopup.widget.PopupDrawerLayout; 19 | import com.lxj.xpopup.widget.VerticalRecyclerView; 20 | import com.lxj.xpopupdemo.R; 21 | import com.lxj.xpopupdemo.custom.CustomDrawerPopupView; 22 | import com.lxj.xpopupdemo.custom.CustomPartShadowPopupView; 23 | 24 | import java.util.ArrayList; 25 | 26 | /** 27 | * Description: 局部阴影的示例 28 | * Create by dance, at 2018/12/21 29 | */ 30 | public class PartShadowDemo extends BaseFragment implements View.OnClickListener { 31 | View ll_container; 32 | VerticalRecyclerView recyclerView; 33 | private CustomPartShadowPopupView popupView; 34 | 35 | private CustomDrawerPopupView drawerPopupView; 36 | 37 | @Override 38 | protected int getLayoutId() { 39 | return R.layout.fragment_part_shadow_demo; 40 | } 41 | 42 | @Override 43 | public void init(View view) { 44 | ll_container = view.findViewById(R.id.ll_container); 45 | recyclerView = view.findViewById(R.id.recyclerView); 46 | 47 | view.findViewById(R.id.tv_all).setOnClickListener(this); 48 | view.findViewById(R.id.tv_price).setOnClickListener(this); 49 | view.findViewById(R.id.tv_sales).setOnClickListener(this); 50 | view.findViewById(R.id.tv_select).setOnClickListener(this); 51 | view.findViewById(R.id.tv_filter).setOnClickListener(this); 52 | 53 | drawerPopupView = new CustomDrawerPopupView(getContext()); 54 | 55 | final ArrayList data = new ArrayList<>(); 56 | for (int i = 0; i < 50; i++) { 57 | data.add(i + ""); 58 | } 59 | CommonAdapter adapter = new CommonAdapter(android.R.layout.simple_list_item_1, data) { 60 | @Override 61 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) { 62 | holder.setText(android.R.id.text1, "长按我试试 - " + position); 63 | //必须要在事件发生之前就watch 64 | final XPopup.Builder builder = new XPopup.Builder(getContext()).watchView(holder.itemView); 65 | holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { 66 | @Override 67 | public boolean onLongClick(View v) { 68 | builder.asAttachList(new String[]{"置顶", "编辑", "删除"}, null,0,10, new OnSelectListener() { 69 | @Override 70 | public void onSelect(int position, String text) { 71 | ToastUtils.showShort(text); 72 | } 73 | }).show(); 74 | return true; 75 | } 76 | }); 77 | } 78 | }; 79 | adapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener(){ 80 | @Override 81 | public void onItemClick(@NonNull View view, @NonNull RecyclerView.ViewHolder holder, int position) { 82 | toast(data.get(position)); 83 | } 84 | }); 85 | recyclerView.setAdapter(adapter); 86 | 87 | } 88 | 89 | 90 | @Override 91 | public void onClick(View v) { 92 | switch (v.getId()) { 93 | case R.id.tv_all: 94 | case R.id.tv_price: 95 | case R.id.tv_sales: 96 | if(popupView==null){ 97 | popupView = (CustomPartShadowPopupView) new XPopup.Builder(getContext()) 98 | .atView(v) 99 | .setPopupCallback(new XPopupCallback() { 100 | @Override 101 | public void onShow() { 102 | Toast.makeText(getActivity(), "显示了", Toast.LENGTH_SHORT).show(); 103 | } 104 | @Override 105 | public void onDismiss() { 106 | Toast.makeText(getActivity(), "关闭了", Toast.LENGTH_SHORT).show(); 107 | } 108 | }) 109 | .asCustom(new CustomPartShadowPopupView(getContext())); 110 | } 111 | popupView.toggle(); 112 | Log.e("tag", "popupView status: "+popupView.popupStatus); 113 | break; 114 | case R.id.tv_filter: 115 | new XPopup.Builder(getContext()) 116 | .popupPosition(PopupPosition.Right)//右边 117 | .hasStatusBarShadow(true) //启用状态栏阴影 118 | .asCustom(drawerPopupView) 119 | .show(); 120 | break; 121 | case R.id.tv_select: 122 | new XPopup.Builder(getContext()) 123 | .atView(v) 124 | .asCustom(new CustomPartShadowPopupView(getContext())) 125 | .show(); 126 | break; 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 |