├── .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 |
24 |
25 |
26 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
20 |
21 |
22 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapter_custom_fullscreen_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapter_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapter_zhihu_comment.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
23 |
24 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_attach_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
19 |
23 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_attach_popup2.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_base_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_bottom_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
27 |
28 |
33 |
34 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_drawer_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
23 |
24 |
32 |
33 |
40 |
41 |
46 |
47 |
54 |
55 |
56 |
63 |
64 |
68 |
69 |
76 |
77 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_edittext_bottom_popup.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
16 |
17 |
25 |
26 |
33 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_fullscreen_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_list_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_part_shadow_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
22 |
23 |
29 |
30 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
15 |
18 |
19 |
25 |
26 |
34 |
35 |
46 |
47 |
48 |
58 |
59 |
60 |
66 |
67 |
73 |
74 |
88 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_popup2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
14 |
15 |
22 |
23 |
27 |
28 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/customxxx.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_all_animator_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
17 |
26 |
27 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_custom_animator_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
17 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_image_preview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
15 |
16 |
23 |
28 |
29 |
35 |
36 |
37 |
44 |
45 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_part_shadow_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
17 |
18 |
22 |
23 |
34 |
35 |
39 |
40 |
51 |
52 |
56 |
57 |
68 |
69 |
73 |
83 |
84 |
85 |
86 |
91 |
92 |
96 |
97 |
107 |
108 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xxhdpi/arrow.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xxhdpi/dropdown.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #008577
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | XPopup
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.2.0'
11 | classpath 'com.novoda:bintray-release:0.9'
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
29 | tasks.getByPath(":library:javadocRelease").enabled = false
30 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jan 31 20:21:17 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion 26
6 |
7 | defaultConfig {
8 | minSdkVersion 15
9 | targetSdkVersion 26
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 |
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 |
21 | }
22 |
23 | dependencies {
24 | implementation fileTree(include: ['*.jar'], dir: 'libs')
25 | implementation 'com.android.support:appcompat-v7:26.0.0'
26 | implementation 'com.android.support:recyclerview-v7:26.0.0'
27 | implementation 'com.android.support:design:26.0.0'
28 | implementation 'com.lxj:easyadapter:1.1.0'
29 | implementation 'com.lxj:xpermission:0.0.2'
30 | }
31 |
32 | publish {
33 | userOrg = 'li-xiaojun'
34 | groupId = 'com.lxj'
35 | artifactId = 'xpopup'
36 | publishVersion = '1.6.9'
37 | repoName = 'jrepo'
38 | desc = '功能强大,UI简洁,交互优雅的通用弹窗!可以替代Dialog,PopupWindow,PopupMenu,BottomSheet,DrawerLayout等组件,自带十几种效果良好的动画, 支持完全的UI和动画自定义!'
39 | website = 'https://github.com/li-xiaojun/XPopup'
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/library/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 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/animator/PopupAnimator.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.animator;
2 |
3 | import android.view.View;
4 |
5 | import com.lxj.xpopup.XPopup;
6 | import com.lxj.xpopup.enums.PopupAnimation;
7 |
8 | /**
9 | * Description: 弹窗动画执行器
10 | * Create by dance, at 2018/12/9
11 | */
12 | public abstract class PopupAnimator {
13 | public View targetView;
14 | public PopupAnimation popupAnimation; // 内置的动画
15 | public PopupAnimator(){}
16 | public PopupAnimator(View target){
17 | this(target, null);
18 | }
19 |
20 | public PopupAnimator(View target, PopupAnimation popupAnimation){
21 | this.targetView = target;
22 | this.popupAnimation = popupAnimation;
23 | }
24 |
25 | public abstract void initAnimator();
26 | public abstract void animateShow();
27 | public abstract void animateDismiss();
28 | public int getDuration(){
29 | return XPopup.getAnimationDuration();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/animator/ScaleAlphaAnimator.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.animator;
2 |
3 | import android.support.v4.view.animation.FastOutSlowInInterpolator;
4 | import android.util.Log;
5 | import android.view.View;
6 | import android.view.ViewTreeObserver;
7 | import android.view.animation.OvershootInterpolator;
8 |
9 | import com.lxj.xpopup.XPopup;
10 | import com.lxj.xpopup.enums.PopupAnimation;
11 |
12 | /**
13 | * Description: 缩放透明
14 | * Create by dance, at 2018/12/9
15 | */
16 | public class ScaleAlphaAnimator extends PopupAnimator {
17 | public ScaleAlphaAnimator(View target, PopupAnimation popupAnimation) {
18 | super(target, popupAnimation);
19 | }
20 |
21 | @Override
22 | public void initAnimator() {
23 | targetView.setScaleX(0f);
24 | targetView.setScaleY(0f);
25 | targetView.setAlpha(0);
26 |
27 | // 设置动画参考点
28 | targetView.post(new Runnable() {
29 | @Override
30 | public void run() {
31 | applyPivot();
32 | }
33 | });
34 | }
35 |
36 | /**
37 | * 根据不同的PopupAnimation来设定对应的pivot
38 | */
39 | private void applyPivot() {
40 | switch (popupAnimation) {
41 | case ScaleAlphaFromCenter:
42 | targetView.setPivotX(targetView.getMeasuredWidth() / 2);
43 | targetView.setPivotY(targetView.getMeasuredHeight() / 2);
44 | break;
45 | case ScaleAlphaFromLeftTop:
46 | targetView.setPivotX(0);
47 | targetView.setPivotY(0);
48 | break;
49 | case ScaleAlphaFromRightTop:
50 | targetView.setPivotX(targetView.getMeasuredWidth());
51 | targetView.setPivotY(0f);
52 | break;
53 | case ScaleAlphaFromLeftBottom:
54 | targetView.setPivotX(0f);
55 | targetView.setPivotY(targetView.getMeasuredHeight());
56 | break;
57 | case ScaleAlphaFromRightBottom:
58 | targetView.setPivotX(targetView.getMeasuredWidth());
59 | targetView.setPivotY(targetView.getMeasuredHeight());
60 | break;
61 | }
62 |
63 | }
64 |
65 | @Override
66 | public void animateShow() {
67 | targetView.animate().scaleX(1f).scaleY(1f).alpha(1f)
68 | .setDuration(XPopup.getAnimationDuration())
69 | .setInterpolator(new OvershootInterpolator(1f))
70 | .start();
71 | }
72 |
73 | @Override
74 | public void animateDismiss() {
75 | targetView.animate().scaleX(0f).scaleY(0f).alpha(0f).setDuration(XPopup.getAnimationDuration())
76 | .setInterpolator(new FastOutSlowInInterpolator()).start();
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/animator/ShadowBgAnimator.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.animator;
2 |
3 | import android.animation.ArgbEvaluator;
4 | import android.animation.ValueAnimator;
5 | import android.graphics.Color;
6 | import android.support.v4.view.animation.FastOutSlowInInterpolator;
7 | import android.view.View;
8 | import android.view.animation.Interpolator;
9 | import android.view.animation.LinearInterpolator;
10 |
11 | import com.lxj.xpopup.XPopup;
12 |
13 | /**
14 | * Description: 背景Shadow动画器,负责执行半透明的渐入渐出动画
15 | * Create by dance, at 2018/12/9
16 | */
17 | public class ShadowBgAnimator extends PopupAnimator {
18 |
19 | public ArgbEvaluator argbEvaluator = new ArgbEvaluator();
20 | public int startColor = Color.TRANSPARENT;
21 | public int endBgColor = Color.parseColor("#77000000");
22 | public ShadowBgAnimator(View target) {
23 | super(target);
24 | }
25 | public ShadowBgAnimator() {}
26 | @Override
27 | public void initAnimator() {
28 | targetView.setBackgroundColor(startColor);
29 | }
30 |
31 | @Override
32 | public void animateShow() {
33 | ValueAnimator animator = ValueAnimator.ofObject(argbEvaluator, startColor, endBgColor);
34 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
35 | @Override
36 | public void onAnimationUpdate(ValueAnimator animation) {
37 | targetView.setBackgroundColor((Integer) animation.getAnimatedValue());
38 | }
39 | });
40 | animator.setDuration(XPopup.getAnimationDuration()).start();
41 | }
42 |
43 | @Override
44 | public void animateDismiss() {
45 | ValueAnimator animator = ValueAnimator.ofObject(argbEvaluator, endBgColor, startColor);
46 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
47 | @Override
48 | public void onAnimationUpdate(ValueAnimator animation) {
49 | targetView.setBackgroundColor((Integer) animation.getAnimatedValue());
50 | }
51 | });
52 | animator.setDuration(XPopup.getAnimationDuration()).start();
53 | }
54 |
55 | public int calculateBgColor(float fraction){
56 | return (int) argbEvaluator.evaluate(fraction, startColor, endBgColor);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/animator/TranslateAlphaAnimator.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.animator;
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.enums.PopupAnimation;
8 | import com.lxj.xpopup.util.XPopupUtils;
9 |
10 | /**
11 | * Description: 平移动画
12 | * Create by dance, at 2018/12/9
13 | */
14 | public class TranslateAlphaAnimator extends PopupAnimator {
15 | //动画起始坐标
16 | private float startTranslationX, startTranslationY;
17 | private float defTranslationX, defTranslationY;
18 | public TranslateAlphaAnimator(View target, PopupAnimation popupAnimation) {
19 | super(target, popupAnimation);
20 | }
21 |
22 | @Override
23 | public void initAnimator() {
24 | defTranslationX = targetView.getTranslationX();
25 | defTranslationY = targetView.getTranslationY();
26 |
27 | targetView.setAlpha(0);
28 | // 设置移动坐标
29 | applyTranslation();
30 | startTranslationX = targetView.getTranslationX();
31 | startTranslationY = targetView.getTranslationY();
32 | }
33 |
34 | private void applyTranslation() {
35 | int halfWidthOffset = XPopupUtils.getWindowWidth(targetView.getContext())/2 - targetView.getMeasuredWidth()/2;
36 | int halfHeightOffset = XPopupUtils.getWindowHeight(targetView.getContext())/2 - targetView.getMeasuredHeight()/2;
37 | switch (popupAnimation){
38 | case TranslateAlphaFromLeft:
39 | targetView.setTranslationX(-(targetView.getMeasuredWidth()/* + halfWidthOffset*/));
40 | break;
41 | case TranslateAlphaFromTop:
42 | targetView.setTranslationY(-(targetView.getMeasuredHeight() /*+ halfHeightOffset*/));
43 | break;
44 | case TranslateAlphaFromRight:
45 | targetView.setTranslationX(targetView.getMeasuredWidth() /*+ halfWidthOffset*/);
46 | break;
47 | case TranslateAlphaFromBottom:
48 | targetView.setTranslationY(targetView.getMeasuredHeight() /*+ halfHeightOffset*/);
49 | break;
50 | }
51 | }
52 |
53 | @Override
54 | public void animateShow() {
55 | targetView.animate().translationX(defTranslationX).translationY(defTranslationY).alpha(1f)
56 | .setInterpolator(new FastOutSlowInInterpolator())
57 | .setDuration(XPopup.getAnimationDuration()).start();
58 | }
59 |
60 | @Override
61 | public void animateDismiss() {
62 | targetView.animate().translationX(startTranslationX).translationY(startTranslationY).alpha(0f)
63 | .setInterpolator(new FastOutSlowInInterpolator())
64 | .setDuration(XPopup.getAnimationDuration()).start();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/animator/TranslateAnimator.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.animator;
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.enums.PopupAnimation;
8 |
9 | /**
10 | * Description: 平移动画,不带渐变
11 | * Create by dance, at 2018/12/9
12 | */
13 | public class TranslateAnimator extends PopupAnimator {
14 | //动画起始坐标
15 | private float startTranslationX, startTranslationY;
16 | private int oldWidth, oldHeight;
17 |
18 | public TranslateAnimator(View target, PopupAnimation popupAnimation) {
19 | super(target, popupAnimation);
20 | }
21 |
22 | @Override
23 | public void initAnimator() {
24 | // 设置起始坐标
25 | applyTranslation();
26 | startTranslationX = targetView.getTranslationX();
27 | startTranslationY = targetView.getTranslationY();
28 | oldWidth = targetView.getMeasuredWidth();
29 | oldHeight = targetView.getMeasuredHeight();
30 | }
31 |
32 | private void applyTranslation() {
33 | switch (popupAnimation){
34 | case TranslateFromLeft:
35 | targetView.setTranslationX(- targetView.getRight());
36 | break;
37 | case TranslateFromTop:
38 | targetView.setTranslationY(- targetView.getBottom());
39 | break;
40 | case TranslateFromRight:
41 | targetView.setTranslationX( ((View)targetView.getParent()).getMeasuredWidth() - targetView.getLeft());
42 | break;
43 | case TranslateFromBottom:
44 | targetView.setTranslationY(((View)targetView.getParent()).getMeasuredHeight() - targetView.getTop());
45 | break;
46 | }
47 | }
48 |
49 | @Override
50 | public void animateShow() {
51 | targetView.animate().translationX(0).translationY(0)
52 | .setInterpolator(new FastOutSlowInInterpolator())
53 | .setDuration(XPopup.getAnimationDuration()).start();
54 | }
55 |
56 | @Override
57 | public void animateDismiss() {
58 | //执行消失动画的时候,宽高可能改变了,所以需要修正动画的起始值
59 | switch (popupAnimation){
60 | case TranslateFromLeft:
61 | startTranslationX -= targetView.getMeasuredWidth() - oldWidth;
62 | break;
63 | case TranslateFromTop:
64 | startTranslationY -= targetView.getMeasuredHeight() - oldHeight;
65 | break;
66 | case TranslateFromRight:
67 | startTranslationX += targetView.getMeasuredWidth() - oldWidth;
68 | break;
69 | case TranslateFromBottom:
70 | startTranslationY += targetView.getMeasuredHeight() - oldHeight;
71 | break;
72 | }
73 | targetView.animate().translationX(startTranslationX).translationY(startTranslationY)
74 | .setInterpolator(new FastOutSlowInInterpolator())
75 | .setDuration(XPopup.getAnimationDuration()).start();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/core/BottomPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.core;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v4.widget.NestedScrollView;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import com.lxj.xpopup.R;
12 | import com.lxj.xpopup.animator.PopupAnimator;
13 | import com.lxj.xpopup.enums.PopupStatus;
14 | import com.lxj.xpopup.util.KeyboardUtils;
15 | import com.lxj.xpopup.util.XPopupUtils;
16 | import com.lxj.xpopup.widget.SmartDragLayout;
17 |
18 | /**
19 | * Description: 在底部显示的Popup
20 | * Create by lxj, at 2018/12/11
21 | */
22 | public class BottomPopupView extends BasePopupView {
23 | protected SmartDragLayout bottomPopupContainer;
24 | public BottomPopupView(@NonNull Context context) {
25 | super(context);
26 | bottomPopupContainer = findViewById(R.id.bottomPopupContainer);
27 | View contentView = LayoutInflater.from(getContext()).inflate(getImplLayoutId(), bottomPopupContainer, false);
28 | bottomPopupContainer.addView(contentView);
29 | }
30 |
31 | @Override
32 | protected int getPopupLayoutId() {
33 | return R.layout._xpopup_bottom_popup_view;
34 | }
35 |
36 | @Override
37 | protected void initPopupContent() {
38 | super.initPopupContent();
39 | bottomPopupContainer.enableDrag(popupInfo.enableDrag);
40 | bottomPopupContainer.dismissOnTouchOutside(popupInfo.isDismissOnTouchOutside);
41 | bottomPopupContainer.hasShadowBg(popupInfo.hasShadowBg);
42 | XPopupUtils.applyPopupSize((ViewGroup) getPopupContentView(), getMaxWidth(), getMaxHeight());
43 |
44 | bottomPopupContainer.setOnCloseListener(new SmartDragLayout.OnCloseListener() {
45 | @Override
46 | public void onClose() {
47 | doAfterDismiss();
48 | }
49 | @Override
50 | public void onOpen() {
51 | BottomPopupView.super.doAfterShow();
52 | }
53 | });
54 |
55 | bottomPopupContainer.setOnClickListener(new OnClickListener() {
56 | @Override
57 | public void onClick(View v) {
58 | dismiss();
59 | }
60 | });
61 | }
62 |
63 | @Override
64 | protected void applyOffset() {
65 | getPopupImplView().setTranslationX(popupInfo.offsetX);
66 | getPopupImplView().setTranslationY(popupInfo.offsetY);
67 | }
68 |
69 | @Override
70 | protected void doAfterShow() {
71 | if(popupInfo.enableDrag){
72 | //do nothing self.
73 | }else {
74 | super.doAfterShow();
75 | }
76 | }
77 |
78 | @Override
79 | public void doShowAnimation() {
80 | if (popupInfo.enableDrag) {
81 | bottomPopupContainer.open();
82 | } else {
83 | super.doShowAnimation();
84 | }
85 | }
86 |
87 | @Override
88 | public void doDismissAnimation() {
89 | if (popupInfo.enableDrag) {
90 | bottomPopupContainer.close();
91 | } else {
92 | super.doDismissAnimation();
93 | }
94 | }
95 |
96 | /**
97 | * 动画是跟随手势发生的,所以不需要额外的动画器,因此动画时间也清零
98 | *
99 | * @return
100 | */
101 | @Override
102 | public int getAnimationDuration() {
103 | return popupInfo.enableDrag ? 0 : super.getAnimationDuration();
104 | }
105 |
106 | @Override
107 | protected PopupAnimator getPopupAnimator() {
108 | // 移除默认的动画器
109 | return popupInfo.enableDrag ? null : super.getPopupAnimator();
110 | }
111 |
112 | @Override
113 | public void dismiss() {
114 | if (popupInfo.enableDrag) {
115 | if (popupStatus == PopupStatus.Dismissing) return;
116 | popupStatus = PopupStatus.Dismissing;
117 | // 关闭Drawer,由于Drawer注册了关闭监听,会自动调用dismiss
118 | bottomPopupContainer.close();
119 | } else {
120 | super.dismiss();
121 | }
122 | }
123 |
124 | /**
125 | * 具体实现的类的布局
126 | *
127 | * @return
128 | */
129 | protected int getImplLayoutId() {
130 | return 0;
131 | }
132 |
133 | protected int getMaxWidth() {
134 | return popupInfo.maxWidth == 0 ? XPopupUtils.getWindowWidth(getContext())
135 | : popupInfo.maxWidth;
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/core/CenterPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.core;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.util.Log;
6 | import android.view.Gravity;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.FrameLayout;
11 | import com.lxj.xpopup.R;
12 | import com.lxj.xpopup.util.XPopupUtils;
13 |
14 | /**
15 | * Description: 在中间显示的Popup
16 | * Create by dance, at 2018/12/8
17 | */
18 | public class CenterPopupView extends BasePopupView {
19 | protected FrameLayout centerPopupContainer;
20 |
21 | public CenterPopupView(@NonNull Context context) {
22 | super(context);
23 | centerPopupContainer = findViewById(R.id.centerPopupContainer);
24 | View contentView = LayoutInflater.from(getContext()).inflate(getImplLayoutId(), centerPopupContainer, false);
25 | LayoutParams params = (LayoutParams) contentView.getLayoutParams();
26 | params.gravity = Gravity.CENTER;
27 | centerPopupContainer.addView(contentView, params);
28 | }
29 |
30 | @Override
31 | protected int getPopupLayoutId() {
32 | return R.layout._xpopup_center_popup_view;
33 | }
34 |
35 | @Override
36 | protected void initPopupContent() {
37 | super.initPopupContent();
38 | XPopupUtils.applyPopupSize((ViewGroup) getPopupContentView(), getMaxWidth(), getMaxHeight());
39 | }
40 |
41 | @Override
42 | protected void applyOffset() {
43 | getPopupContentView().setTranslationX(popupInfo.offsetX);
44 | getPopupContentView().setTranslationY(popupInfo.offsetY);
45 | }
46 |
47 | /**
48 | * 具体实现的类的布局
49 | *
50 | * @return
51 | */
52 | protected int getImplLayoutId() {
53 | return 0;
54 | }
55 |
56 | protected int getMaxWidth() {
57 | return popupInfo.maxWidth==0 ? (int) (XPopupUtils.getWindowWidth(getContext()) * 0.86f)
58 | : popupInfo.maxWidth;
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/core/DrawerPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.core;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.widget.FrameLayout;
8 | import com.lxj.xpopup.R;
9 | import com.lxj.xpopup.enums.PopupPosition;
10 | import com.lxj.xpopup.widget.PopupDrawerLayout;
11 |
12 | /**
13 | * Description: 带Drawer的弹窗
14 | * Create by dance, at 2018/12/20
15 | */
16 | public abstract class DrawerPopupView extends BasePopupView {
17 | PopupDrawerLayout drawerLayout;
18 | protected FrameLayout drawerContentContainer;
19 |
20 | public DrawerPopupView(@NonNull Context context) {
21 | super(context);
22 | drawerLayout = findViewById(R.id.drawerLayout);
23 | drawerContentContainer = findViewById(R.id.drawerContentContainer);
24 | View contentView = LayoutInflater.from(getContext()).inflate(getImplLayoutId(), drawerContentContainer, false);
25 | drawerContentContainer.addView(contentView);
26 | }
27 |
28 | @Override
29 | protected int getPopupLayoutId() {
30 | return R.layout._xpopup_drawer_popup_view;
31 | }
32 |
33 | @Override
34 | protected void initPopupContent() {
35 | super.initPopupContent();
36 | drawerLayout.setOnCloseListener(new PopupDrawerLayout.OnCloseListener() {
37 | @Override
38 | public void onClose() {
39 | DrawerPopupView.super.dismiss();
40 | }
41 |
42 | @Override
43 | public void onOpen() {
44 | DrawerPopupView.super.doAfterShow();
45 | }
46 |
47 | @Override
48 | public void onDismissing(float fraction) {
49 | drawerLayout.isDrawStatusBarShadow = popupInfo.hasStatusBarShadow;
50 | }
51 | });
52 | drawerLayout.setDrawerPosition(popupInfo.popupPosition == null ? PopupPosition.Left : popupInfo.popupPosition);
53 | drawerLayout.setOnClickListener(new OnClickListener() {
54 | @Override
55 | public void onClick(View v) {
56 | drawerLayout.close();
57 | }
58 | });
59 | }
60 | @Override
61 | protected void applyOffset() {
62 | getPopupImplView().setTranslationX(popupInfo.offsetX);
63 | getPopupImplView().setTranslationY(popupInfo.offsetY);
64 | }
65 | @Override
66 | protected void doAfterShow() {
67 | //do nothing self.
68 | }
69 |
70 | @Override
71 | public void doShowAnimation() {
72 | drawerLayout.open();
73 | }
74 |
75 | @Override
76 | public void doDismissAnimation() {
77 | drawerLayout.close();
78 | }
79 |
80 | /**
81 | * 动画是跟随手势发生的,所以不需要额外的动画器,因此动画时间也清零
82 | *
83 | * @return
84 | */
85 | @Override
86 | public int getAnimationDuration() {
87 | return 0;
88 | }
89 |
90 | @Override
91 | public void dismiss() {
92 | // 关闭Drawer,由于Drawer注册了关闭监听,会自动调用dismiss
93 | drawerLayout.close();
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/core/HorizontalAttachPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.core;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.graphics.Rect;
6 | import android.os.Build;
7 | import android.support.annotation.NonNull;
8 |
9 | import com.lxj.xpopup.R;
10 | import com.lxj.xpopup.animator.PopupAnimator;
11 | import com.lxj.xpopup.animator.ScrollScaleAnimator;
12 | import com.lxj.xpopup.enums.PopupAnimation;
13 | import com.lxj.xpopup.enums.PopupPosition;
14 | import com.lxj.xpopup.util.XPopupUtils;
15 |
16 | /**
17 | * Description: 水平方向的依附于某个View或者某个点的弹窗,可以轻松实现微信朋友圈点赞的弹窗效果。
18 | * 支持通过popupPosition()方法手动指定想要出现在目标的左边还是右边,但是对Top和Bottom则不生效。
19 | * Create by lxj, at 2019/3/13
20 | */
21 | public class HorizontalAttachPopupView extends AttachPopupView {
22 | public HorizontalAttachPopupView(@NonNull Context context) {
23 | super(context);
24 | }
25 |
26 | @Override
27 | protected void initPopupContent() {
28 | super.initPopupContent();
29 | defaultOffsetY = popupInfo.offsetY == 0 ? XPopupUtils.dp2px(getContext(), 0) : popupInfo.offsetY;
30 | defaultOffsetX = popupInfo.offsetX == 0 ? XPopupUtils.dp2px(getContext(), 4) : popupInfo.offsetX;
31 | if (!popupInfo.hasShadowBg) {
32 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
33 | defaultOffsetX -= bgDrawableMargin;
34 | defaultOffsetY -= bgDrawableMargin;
35 | }
36 | }
37 | }
38 |
39 | /**
40 | * 执行附着逻辑
41 | */
42 | protected void doAttach() {
43 | float translationX = 0, translationY = 0;
44 | int w = getPopupContentView().getMeasuredWidth();
45 | int h = getPopupContentView().getMeasuredHeight();
46 | //0. 判断是依附于某个点还是某个View
47 | if (popupInfo.touchPoint != null) {
48 | // 依附于指定点
49 | isShowLeft = popupInfo.touchPoint.x > XPopupUtils.getWindowWidth(getContext()) / 2;
50 |
51 | // translationX: 在左边就和点左边对齐,在右边就和其右边对齐
52 | translationX = isShowLeftToTarget() ? (popupInfo.touchPoint.x - w - defaultOffsetX) : (popupInfo.touchPoint.x + defaultOffsetX);
53 | translationY = popupInfo.touchPoint.y - h * .5f + defaultOffsetY;
54 | } else {
55 | // 依附于指定View
56 | //1. 获取atView在屏幕上的位置
57 | int[] locations = new int[2];
58 | popupInfo.getAtView().getLocationOnScreen(locations);
59 | Rect rect = new Rect(locations[0], locations[1], locations[0] + popupInfo.getAtView().getMeasuredWidth(),
60 | locations[1] + popupInfo.getAtView().getMeasuredHeight());
61 |
62 | int centerX = (rect.left + rect.right) / 2;
63 |
64 | isShowLeft = centerX > XPopupUtils.getWindowWidth(getContext()) / 2;
65 |
66 | translationX = isShowLeftToTarget() ? (rect.left - w - defaultOffsetX) : (rect.right + defaultOffsetX);
67 | translationY = rect.top + (rect.height()-h)/2 + defaultOffsetY;
68 | }
69 | getPopupContentView().setTranslationX(translationX);
70 | getPopupContentView().setTranslationY(translationY);
71 | }
72 |
73 | private boolean isShowLeftToTarget() {
74 | return (isShowLeft || popupInfo.popupPosition == PopupPosition.Left)
75 | && popupInfo.popupPosition != PopupPosition.Right;
76 | }
77 |
78 | @Override
79 | protected PopupAnimator getPopupAnimator() {
80 | ScrollScaleAnimator animator;
81 | if (isShowLeftToTarget()) {
82 | animator = new ScrollScaleAnimator(getPopupContentView(), PopupAnimation.ScrollAlphaFromRight);
83 | } else {
84 | animator = new ScrollScaleAnimator(getPopupContentView(), PopupAnimation.ScrollAlphaFromLeft);
85 | }
86 | animator.isOnlyScaleX = true;
87 | return animator;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/core/PopupInfo.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.core;
2 |
3 | import android.graphics.PointF;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import com.lxj.xpopup.animator.PopupAnimator;
7 | import com.lxj.xpopup.enums.PopupAnimation;
8 | import com.lxj.xpopup.enums.PopupPosition;
9 | import com.lxj.xpopup.enums.PopupType;
10 | import com.lxj.xpopup.interfaces.XPopupCallback;
11 |
12 | /**
13 | * Description: Popup的属性封装
14 | * Create by dance, at 2018/12/8
15 | */
16 | public class PopupInfo {
17 | public PopupType popupType = null; //窗体的类型
18 | public Boolean isDismissOnBackPressed = true; //按返回键是否消失
19 | public Boolean isDismissOnTouchOutside = true; //点击外部消失
20 | public Boolean autoDismiss = true; //操作完毕后是否自动关闭
21 | public Boolean hasShadowBg = true; // 是否有半透明的背景
22 | public View atView = null; // 依附于那个View显示
23 | public View watchView = null; // 依附于那个View显示
24 | // 动画执行器,如果不指定,则会根据窗体类型popupType字段生成默认合适的动画执行器
25 | public PopupAnimation popupAnimation = null;
26 | public PopupAnimator customAnimator = null;
27 | public PointF touchPoint = null; // 触摸的点
28 | public int maxWidth; // 最大宽度
29 | public int maxHeight; // 最大高度
30 | public Boolean autoOpenSoftInput = false;//是否自动打开输入法
31 | public XPopupCallback xPopupCallback;
32 |
33 | public ViewGroup decorView; //每个弹窗所属的DecorView
34 | public Boolean isMoveUpToKeyboard = true; //是否移动到软键盘上面,默认弹窗会移到软键盘上面
35 | public PopupPosition popupPosition = null; //弹窗出现在目标的什么位置
36 | public Boolean hasStatusBarShadow = false;
37 | public int offsetX, offsetY;//x,y方向的偏移量
38 | public Boolean enableDrag = true;//是否启用拖拽
39 | public boolean isCenterHorizontal = false;//是否水平居中
40 | public boolean isRequestFocus = true; //弹窗是否抢占焦点
41 |
42 | public View getAtView() {
43 | return atView;
44 | }
45 | public void setAtView(View atView) {
46 | this.atView = atView;
47 | this.popupType = PopupType.AttachView;
48 | }
49 |
50 | @Override
51 | public String toString() {
52 | return "PopupInfo{" +
53 | "popupType=" + popupType +
54 | ", isDismissOnBackPressed=" + isDismissOnBackPressed +
55 | ", isDismissOnTouchOutside=" + isDismissOnTouchOutside +
56 | ", hasShadowBg=" + hasShadowBg +
57 | ", atView=" + atView +
58 | ", popupAnimation=" + popupAnimation +
59 | ", customAnimator=" + customAnimator +
60 | ", touchPoint=" + touchPoint +
61 | ", maxWidth=" + maxWidth +
62 | ", maxHeight=" + maxHeight +
63 | '}';
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/enums/ImageType.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.enums;
2 |
3 | /**
4 | * Description:
5 | * Create by lxj, at 2019/3/4
6 | */
7 | public enum ImageType {
8 | GIF(true),
9 | JPEG(false),
10 | RAW(false),
11 | /** PNG type with alpha. */
12 | PNG_A(true),
13 | /** PNG type without alpha. */
14 | PNG(false),
15 | /** WebP type with alpha. */
16 | WEBP_A(true),
17 | /** WebP type without alpha. */
18 | WEBP(false),
19 | /** Unrecognized type. */
20 | UNKNOWN(false);
21 |
22 | private final boolean hasAlpha;
23 |
24 | ImageType(boolean hasAlpha) {
25 | this.hasAlpha = hasAlpha;
26 | }
27 |
28 | public boolean hasAlpha() {
29 | return hasAlpha;
30 | }
31 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/enums/LayoutStatus.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.enums;
2 |
3 | /**
4 | * Description:
5 | * Create by lxj, at 2019/2/22
6 | */
7 | public enum LayoutStatus {
8 | Open, Close, Opening, Closing
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/enums/PopupAnimation.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.enums;
2 |
3 | /**
4 | * Description:
5 | * Create by dance, at 2018/12/9
6 | */
7 | public enum PopupAnimation {
8 | // 缩放 + 透明渐变
9 | ScaleAlphaFromCenter, // 从中心进行缩放+透明渐变
10 | ScaleAlphaFromLeftTop, //从左上角进行缩放+透明渐变
11 | ScaleAlphaFromRightTop, //从右上角进行缩放+透明渐变
12 | ScaleAlphaFromLeftBottom, //从左下角进行缩放+透明渐变
13 | ScaleAlphaFromRightBottom, //从右下角进行缩放+透明渐变
14 |
15 | // 平移 + 透明渐变
16 | TranslateAlphaFromLeft, // 从左平移进入
17 | TranslateAlphaFromRight, // 从右平移进入
18 | TranslateAlphaFromTop, // 从上方平移进入
19 | TranslateAlphaFromBottom, // 从下方平移进入
20 |
21 | // 平移,不带透明渐变
22 | TranslateFromLeft, // 从左平移进入
23 | TranslateFromRight, // 从右平移进入
24 | TranslateFromTop, // 从上方平移进入
25 | TranslateFromBottom, // 从下方平移进入
26 |
27 | // 滑动 + 透明渐变
28 | ScrollAlphaFromLeft,
29 | ScrollAlphaFromLeftTop,
30 | ScrollAlphaFromTop,
31 | ScrollAlphaFromRightTop,
32 | ScrollAlphaFromRight,
33 | ScrollAlphaFromRightBottom,
34 | ScrollAlphaFromBottom,
35 | ScrollAlphaFromLeftBottom,
36 | }
37 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/enums/PopupPosition.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.enums;
2 |
3 | /**
4 | * Description: 弹窗相对于目标View显示的位置
5 | * Create by dance, at 2019/3/26
6 | */
7 | public enum PopupPosition {
8 | Left, Right, Top, Bottom
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/enums/PopupStatus.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.enums;
2 |
3 | /**
4 | * Description: Popup显示和隐藏状态
5 | * Create by dance, at 2018/12/9
6 | */
7 | public enum PopupStatus {
8 | Show, // 显示
9 | Showing, // 正在执行显示动画
10 | Dismiss, // 隐藏
11 | Dismissing //正在执行消失动画
12 | }
13 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/enums/PopupType.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.enums;
2 |
3 | /**
4 | * Description: 窗体显示的位置类型
5 | * Create by lxj, at 2018/12/7
6 | */
7 | public enum PopupType {
8 | Center, // 中间显示类型
9 | Bottom, // 底部弹出的类型
10 | AttachView, // 依附于指定View或者指定Point的类型
11 | ImageViewer // 大图浏览类型
12 | }
13 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/impl/AttachListPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.impl;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.os.Build;
6 | import android.support.annotation.NonNull;
7 | import android.support.v7.widget.RecyclerView;
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.R;
14 | import com.lxj.xpopup.core.AttachPopupView;
15 | import com.lxj.xpopup.interfaces.OnSelectListener;
16 | import com.lxj.xpopup.util.XPopupUtils;
17 |
18 | import java.util.Arrays;
19 |
20 | /**
21 | * Description: Attach类型的列表弹窗
22 | * Create by dance, at 2018/12/12
23 | */
24 | public class AttachListPopupView extends AttachPopupView {
25 | RecyclerView recyclerView;
26 |
27 | public AttachListPopupView(@NonNull Context context) {
28 | super(context);
29 | }
30 |
31 |
32 | @Override
33 | protected int getImplLayoutId() {
34 | return R.layout._xpopup_attach_impl_list;
35 | }
36 |
37 | @Override
38 | protected void initPopupContent() {
39 | super.initPopupContent();
40 | recyclerView = findViewById(R.id.recyclerView);
41 | final CommonAdapter adapter = new CommonAdapter(R.layout._xpopup_adapter_text, Arrays.asList(data)) {
42 | @Override
43 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {
44 | holder.setText(R.id.tv_text, s);
45 | if (iconIds != null && iconIds.length > position) {
46 | holder.setVisible(R.id.iv_image, true);
47 | holder.setBackgroundRes(R.id.iv_image, iconIds[position]);
48 | }else {
49 | holder.setVisible(R.id.iv_image, false);
50 | }
51 | }
52 | };
53 | adapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener() {
54 | @Override
55 | public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
56 | if (selectListener != null) {
57 | selectListener.onSelect(position, adapter.getDatas().get(position));
58 | }
59 | if(popupInfo.autoDismiss)dismiss();
60 | }
61 | });
62 | recyclerView.setAdapter(adapter);
63 | }
64 |
65 | String[] data;
66 | int[] iconIds;
67 | public AttachListPopupView setStringData(String[] data, int[] iconIds) {
68 | this.data = data;
69 | this.iconIds = iconIds;
70 | return this;
71 | }
72 |
73 | public AttachListPopupView setOffsetXAndY(int offsetX, int offsetY) {
74 | this.defaultOffsetX += offsetX;
75 | this.defaultOffsetY += offsetY;
76 | return this;
77 | }
78 |
79 | private OnSelectListener selectListener;
80 |
81 | public AttachListPopupView setOnSelectListener(OnSelectListener selectListener) {
82 | this.selectListener = selectListener;
83 | return this;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/impl/BottomListPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.impl;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.text.TextUtils;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.widget.TextView;
10 |
11 | import com.lxj.easyadapter.CommonAdapter;
12 | import com.lxj.easyadapter.MultiItemTypeAdapter;
13 | import com.lxj.easyadapter.ViewHolder;
14 | import com.lxj.xpopup.R;
15 | import com.lxj.xpopup.XPopup;
16 | import com.lxj.xpopup.core.BottomPopupView;
17 | import com.lxj.xpopup.interfaces.OnSelectListener;
18 | import com.lxj.xpopup.widget.CheckView;
19 |
20 | import java.util.Arrays;
21 |
22 | /**
23 | * Description: 底部的列表对话框
24 | * Create by dance, at 2018/12/16
25 | */
26 | public class BottomListPopupView extends BottomPopupView {
27 | RecyclerView recyclerView;
28 | TextView tv_title;
29 | public BottomListPopupView(@NonNull Context context) {
30 | super(context);
31 | }
32 |
33 | @Override
34 | protected int getImplLayoutId() {
35 | return R.layout._xpopup_center_impl_list;
36 | }
37 |
38 | @Override
39 | protected void initPopupContent() {
40 | super.initPopupContent();
41 | recyclerView = findViewById(R.id.recyclerView);
42 | tv_title = findViewById(R.id.tv_title);
43 |
44 | if(TextUtils.isEmpty(title)){
45 | tv_title.setVisibility(GONE);
46 | }else {
47 | tv_title.setText(title);
48 | }
49 |
50 | final CommonAdapter adapter = new CommonAdapter(R.layout._xpopup_adapter_text, Arrays.asList(data)) {
51 | @Override
52 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {
53 | holder.setText(R.id.tv_text, s);
54 | if (iconIds != null && iconIds.length > position) {
55 | holder.setVisible(R.id.iv_image, true);
56 | holder.setBackgroundRes(R.id.iv_image, iconIds[position]);
57 | }else {
58 | holder.setVisible(R.id.iv_image, false);
59 | }
60 |
61 | // 对勾View
62 | if (checkedPosition != -1) {
63 | holder.setVisible(R.id.check_view, position == checkedPosition);
64 | holder.getView(R.id.check_view).setColor(XPopup.getPrimaryColor());
65 | holder.setTextColor(R.id.tv_text, position==checkedPosition ?
66 | XPopup.getPrimaryColor() : getResources().getColor(R.color._xpopup_title_color));
67 | }
68 | }
69 | };
70 | adapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener() {
71 | @Override
72 | public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
73 | if (selectListener != null) {
74 | selectListener.onSelect(position, adapter.getDatas().get(position));
75 | }
76 | if (checkedPosition!=-1){
77 | checkedPosition = position;
78 | adapter.notifyDataSetChanged();
79 | }
80 | postDelayed(new Runnable() {
81 | @Override
82 | public void run() {
83 | if(popupInfo.autoDismiss)dismiss();
84 | }
85 | },100);
86 | }
87 | });
88 | recyclerView.setHasFixedSize(true);
89 | recyclerView.setAdapter(adapter);
90 | }
91 |
92 | String title;
93 | String[] data;
94 | int[] iconIds;
95 | public BottomListPopupView setStringData(String title, String[] data, int[] iconIds) {
96 | this.title = title;
97 | this.data = data;
98 | this.iconIds = iconIds;
99 | return this;
100 | }
101 |
102 | private OnSelectListener selectListener;
103 | public BottomListPopupView setOnSelectListener(OnSelectListener selectListener) {
104 | this.selectListener = selectListener;
105 | return this;
106 | }
107 |
108 | int checkedPosition = -1;
109 | /**
110 | * 设置默认选中的位置
111 | *
112 | * @param position
113 | * @return
114 | */
115 | public BottomListPopupView setCheckedPosition(int position) {
116 | this.checkedPosition = position;
117 | return this;
118 | }
119 |
120 |
121 | }
122 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/impl/CenterListPopupView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.impl;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.text.TextUtils;
7 | import android.view.View;
8 | import android.widget.TextView;
9 |
10 | import com.lxj.easyadapter.CommonAdapter;
11 | import com.lxj.easyadapter.MultiItemTypeAdapter;
12 | import com.lxj.easyadapter.ViewHolder;
13 | import com.lxj.xpopup.R;
14 | import com.lxj.xpopup.XPopup;
15 | import com.lxj.xpopup.core.CenterPopupView;
16 | import com.lxj.xpopup.interfaces.OnSelectListener;
17 | import com.lxj.xpopup.widget.CheckView;
18 |
19 | import java.util.Arrays;
20 |
21 | /**
22 | * Description: 在中间的列表对话框
23 | * Create by dance, at 2018/12/16
24 | */
25 | public class CenterListPopupView extends CenterPopupView {
26 | RecyclerView recyclerView;
27 | TextView tv_title;
28 |
29 | public CenterListPopupView(@NonNull Context context) {
30 | super(context);
31 | }
32 |
33 | @Override
34 | protected int getImplLayoutId() {
35 | return R.layout._xpopup_center_impl_list;
36 | }
37 |
38 | @Override
39 | protected void initPopupContent() {
40 | super.initPopupContent();
41 | recyclerView = findViewById(R.id.recyclerView);
42 | tv_title = findViewById(R.id.tv_title);
43 |
44 | if (TextUtils.isEmpty(title)) {
45 | tv_title.setVisibility(GONE);
46 | } else {
47 | tv_title.setText(title);
48 | }
49 |
50 | final CommonAdapter adapter = new CommonAdapter(R.layout._xpopup_adapter_text, Arrays.asList(data)) {
51 | @Override
52 | protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {
53 | holder.setText(R.id.tv_text, s);
54 | if (iconIds != null && iconIds.length > position) {
55 | holder.setVisible(R.id.iv_image, true);
56 | holder.setBackgroundRes(R.id.iv_image, iconIds[position]);
57 | } else {
58 | holder.setVisible(R.id.iv_image, false);
59 | }
60 |
61 | // 对勾View
62 | if (checkedPosition != -1) {
63 | holder.setVisible(R.id.check_view, position == checkedPosition);
64 | holder.getView(R.id.check_view).setColor(XPopup.getPrimaryColor());
65 | holder.setTextColor(R.id.tv_text, position==checkedPosition ?
66 | XPopup.getPrimaryColor() : getResources().getColor(R.color._xpopup_title_color));
67 | }
68 | }
69 | };
70 | adapter.setOnItemClickListener(new MultiItemTypeAdapter.SimpleOnItemClickListener() {
71 | @Override
72 | public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
73 | if (selectListener != null) {
74 | if(position>=0 && position getMeasuredHeight()/2){
57 | // 说明atView在Window下半部分,PartShadow应该显示在它上方,计算atView之上的高度
58 | params.height = rect.top;
59 | isShowUp = true;
60 | getPopupContentView().setTranslationY(-defaultOffsetY);
61 |
62 | // 同时自定义的impl View应该Gravity居于底部
63 | View implView = ((ViewGroup)getPopupContentView()).getChildAt(0);
64 | FrameLayout.LayoutParams implParams = (LayoutParams) implView.getLayoutParams();
65 | implParams.gravity = Gravity.BOTTOM;
66 | if(getMaxHeight()!=0)
67 | implParams.height = Math.min(implView.getMeasuredHeight(), getMaxHeight());
68 | implView.setLayoutParams(implParams);
69 |
70 | } else {
71 | // atView在上半部分,PartShadow应该显示在它下方,计算atView之下的高度
72 | params.height = getMeasuredHeight() - rect.bottom;
73 | // 防止伸到导航栏下面
74 | if(XPopupUtils.isNavBarVisible(getContext())){
75 | params.height -= XPopupUtils.getNavBarHeight();
76 | }
77 | isShowUp = false;
78 | getPopupContentView().setTranslationY(rect.bottom + defaultOffsetY);
79 |
80 | // 同时自定义的impl View应该Gravity居于顶部
81 | View implView = ((ViewGroup)getPopupContentView()).getChildAt(0);
82 | FrameLayout.LayoutParams implParams = (LayoutParams) implView.getLayoutParams();
83 | implParams.gravity = Gravity.TOP;
84 | if(getMaxHeight()!=0)
85 | implParams.height = Math.min(implView.getMeasuredHeight(), getMaxHeight());
86 | implView.setLayoutParams(implParams);
87 | }
88 | getPopupContentView().setLayoutParams(params);
89 |
90 | attachPopupContainer.setOnClickOutsideListener(new OnClickOutsideListener() {
91 | @Override
92 | public void onClickOutside() {
93 | dismiss();
94 | }
95 | });
96 | }
97 |
98 | //让触摸透过
99 | @Override
100 | public boolean onTouchEvent(MotionEvent event) {
101 | dismiss();
102 | return false;
103 | }
104 |
105 | @Override
106 | protected PopupAnimator getPopupAnimator() {
107 | return new TranslateAnimator(getPopupImplView(), isShowUp ?
108 | PopupAnimation.TranslateFromBottom: PopupAnimation.TranslateFromTop);
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnCancelListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | /**
4 | * Description:
5 | * Create by dance, at 2018/12/17
6 | */
7 | public interface OnCancelListener {
8 | void onCancel();
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnClickOutsideListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | /**
4 | * Description:
5 | * Create by dance, at 2019/1/10
6 | */
7 | public interface OnClickOutsideListener {
8 | void onClickOutside();
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnConfirmListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | /**
4 | * Description:
5 | * Create by dance, at 2018/12/17
6 | */
7 | public interface OnConfirmListener {
8 | void onConfirm();
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnDragChangeListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | public interface OnDragChangeListener {
4 | void onRelease();
5 | void onDragChange(int dy, float scale, float fraction);
6 | }
7 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnInputConfirmListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | /**
4 | * Description:
5 | * Create by dance, at 2018/12/17
6 | */
7 | public interface OnInputConfirmListener {
8 | void onConfirm(String text);
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnSelectListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | /**
4 | * Description:
5 | * Create by dance, at 2018/12/17
6 | */
7 | public interface OnSelectListener {
8 | void onSelect(int position, String text);
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/OnSrcViewUpdateListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | import android.support.annotation.NonNull;
4 |
5 | import com.lxj.xpopup.core.ImageViewerPopupView;
6 |
7 | /**
8 | * Description:
9 | * Create by dance, at 2019/1/29
10 | */
11 | public interface OnSrcViewUpdateListener {
12 | void onSrcViewUpdate(@NonNull ImageViewerPopupView popupView, int position);
13 | }
14 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/XPopupCallback.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | /**
4 | * Description: XPopup显示和隐藏的回调接口
5 | * Create by dance, at 2018/12/21
6 | */
7 | public interface XPopupCallback {
8 | /**
9 | * 完全显示的时候执行
10 | */
11 | void onShow();
12 |
13 | /**
14 | * 完全消失的时候执行
15 | */
16 | void onDismiss();
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/interfaces/XPopupImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.interfaces;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.widget.ImageView;
6 |
7 | import java.io.File;
8 |
9 | public interface XPopupImageLoader{
10 | void loadImage(int position, @NonNull Object uri, @NonNull ImageView imageView);
11 |
12 | /**
13 | * 获取图片对应的文件
14 | * @param context
15 | * @param uri
16 | * @return
17 | */
18 | File getImageFile(@NonNull Context context, @NonNull Object uri);
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/Compat.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2011, 2012 Chris Banes.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.lxj.xpopup.photoview;
17 |
18 | import android.annotation.TargetApi;
19 | import android.os.Build.VERSION;
20 | import android.os.Build.VERSION_CODES;
21 | import android.view.View;
22 |
23 | class Compat {
24 |
25 | private static final int SIXTY_FPS_INTERVAL = 1000 / 60;
26 |
27 | public static void postOnAnimation(View view, Runnable runnable) {
28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
29 | postOnAnimationJellyBean(view, runnable);
30 | } else {
31 | view.postDelayed(runnable, SIXTY_FPS_INTERVAL);
32 | }
33 | }
34 |
35 | @TargetApi(16)
36 | private static void postOnAnimationJellyBean(View view, Runnable runnable) {
37 | view.postOnAnimation(runnable);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnGestureListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2011, 2012 Chris Banes.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.lxj.xpopup.photoview;
17 |
18 | interface OnGestureListener {
19 |
20 | void onDrag(float dx, float dy);
21 |
22 | void onFling(float startX, float startY, float velocityX,
23 | float velocityY);
24 |
25 | void onScale(float scaleFactor, float focusX, float focusY);
26 |
27 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnMatrixChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for
7 | * this View.
8 | */
9 | public interface OnMatrixChangedListener {
10 |
11 | /**
12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because
13 | * the View's bounds have changed, or the user has zoomed.
14 | *
15 | * @param rect - Rectangle displaying the Drawable's new bounds.
16 | */
17 | void onMatrixChanged(RectF rect);
18 | }
19 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnOutsidePhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Callback when the user tapped outside of the photo
7 | */
8 | public interface OnOutsidePhotoTapListener {
9 |
10 | /**
11 | * The outside of the photo has been tapped
12 | */
13 | void onOutsidePhotoTap(ImageView imageView);
14 | }
15 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnPhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * A callback to be invoked when the Photo is tapped with a single
7 | * tap.
8 | */
9 | public interface OnPhotoTapListener {
10 |
11 | /**
12 | * A callback to receive where the user taps on a photo. You will only receive a callback if
13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored.
14 | *
15 | * @param view ImageView the user tapped.
16 | * @param x where the user tapped from the of the Drawable, as percentage of the
17 | * Drawable width.
18 | * @param y where the user tapped from the top of the Drawable, as percentage of the
19 | * Drawable height.
20 | */
21 | void onPhotoTap(ImageView view, float x, float y);
22 | }
23 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnScaleChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 |
4 | /**
5 | * Interface definition for callback to be invoked when attached ImageView scale changes
6 | */
7 | public interface OnScaleChangedListener {
8 |
9 | /**
10 | * Callback for when the scale changes
11 | *
12 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in)
13 | * @param focusX focal point X position
14 | * @param focusY focal point Y position
15 | */
16 | void onScaleChange(float scaleFactor, float focusX, float focusY);
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnSingleFlingListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | import android.view.MotionEvent;
4 |
5 | /**
6 | * A callback to be invoked when the ImageView is flung with a single
7 | * touch
8 | */
9 | public interface OnSingleFlingListener {
10 |
11 | /**
12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if
13 | * the user flings anywhere on the view.
14 | *
15 | * @param e1 MotionEvent the user first touch.
16 | * @param e2 MotionEvent the user last touch.
17 | * @param velocityX distance of user's horizontal fling.
18 | * @param velocityY distance of user's vertical fling.
19 | */
20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
21 | }
22 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnViewDragListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | /**
4 | * Interface definition for a callback to be invoked when the photo is experiencing a drag event
5 | */
6 | public interface OnViewDragListener {
7 |
8 | /**
9 | * Callback for when the photo is experiencing a drag event. This cannot be invoked when the
10 | * user is scaling.
11 | *
12 | * @param dx The change of the coordinates in the x-direction
13 | * @param dy The change of the coordinates in the y-direction
14 | */
15 | void onDrag(float dx, float dy);
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/OnViewTapListener.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | import android.view.View;
4 |
5 | public interface OnViewTapListener {
6 |
7 | /**
8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if
9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored.
10 | *
11 | * @param view - View the user tapped.
12 | * @param x - where the user tapped from the left of the View.
13 | * @param y - where the user tapped from the top of the View.
14 | */
15 | void onViewTap(View view, float x, float y);
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/photoview/Util.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.photoview;
2 |
3 | import android.view.MotionEvent;
4 | import android.widget.ImageView;
5 |
6 | class Util {
7 |
8 | static void checkZoomLevels(float minZoom, float midZoom,
9 | float maxZoom) {
10 | if (minZoom >= midZoom) {
11 | throw new IllegalArgumentException(
12 | "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value");
13 | } else if (midZoom >= maxZoom) {
14 | throw new IllegalArgumentException(
15 | "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value");
16 | }
17 | }
18 |
19 | static boolean hasDrawable(ImageView imageView) {
20 | return imageView.getDrawable() != null;
21 | }
22 |
23 | static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) {
24 | if (scaleType == null) {
25 | return false;
26 | }
27 | switch (scaleType) {
28 | case MATRIX:
29 | // throw new IllegalStateException("Matrix scale type is not supported");
30 | return false;
31 | }
32 | return true;
33 | }
34 |
35 | static int getPointerIndex(int action) {
36 | return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/util/ImageHeaderParser.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.util;
2 |
3 | import com.lxj.xpopup.enums.ImageType;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import static com.lxj.xpopup.enums.ImageType.GIF;
8 | import static com.lxj.xpopup.enums.ImageType.JPEG;
9 | import static com.lxj.xpopup.enums.ImageType.PNG;
10 | import static com.lxj.xpopup.enums.ImageType.PNG_A;
11 | import static com.lxj.xpopup.enums.ImageType.UNKNOWN;
12 |
13 | /**
14 | * Description: copy from Glide.
15 | * Create by lxj, at 2019/3/4
16 | */
17 | public class ImageHeaderParser {
18 | private static final int GIF_HEADER = 0x474946;
19 | private static final int PNG_HEADER = 0x89504E47;
20 | static final int EXIF_MAGIC_NUMBER = 0xFFD8;
21 | // WebP-related
22 | // "RIFF"
23 | private static final int RIFF_HEADER = 0x52494646;
24 | // "WEBP"
25 | private static final int WEBP_HEADER = 0x57454250;
26 | // "VP8" null.
27 | private static final int VP8_HEADER = 0x56503800;
28 | private static final int VP8_HEADER_MASK = 0xFFFFFF00;
29 | private static final int VP8_HEADER_TYPE_MASK = 0x000000FF;
30 | // 'X'
31 | private static final int VP8_HEADER_TYPE_EXTENDED = 0x00000058;
32 | // 'L'
33 | private static final int VP8_HEADER_TYPE_LOSSLESS = 0x0000004C;
34 | private static final int WEBP_EXTENDED_ALPHA_FLAG = 1 << 4;
35 | private static final int WEBP_LOSSLESS_ALPHA_FLAG = 1 << 3;
36 |
37 | static ImageType getImageType(InputStream is) throws IOException{
38 | Reader reader = new StreamReader(is);
39 | final int firstTwoBytes = reader.getUInt16();
40 |
41 | // JPEG.
42 | if (firstTwoBytes == EXIF_MAGIC_NUMBER) {
43 | return JPEG;
44 | }
45 |
46 | final int firstFourBytes = (firstTwoBytes << 16 & 0xFFFF0000) | (reader.getUInt16() & 0xFFFF);
47 | // PNG.
48 | if (firstFourBytes == PNG_HEADER) {
49 | // See: http://stackoverflow.com/questions/2057923/how-to-check-a-png-for-grayscale-alpha
50 | // -color-type
51 | reader.skip(25 - 4);
52 | int alpha = reader.getByte();
53 | // A RGB indexed PNG can also have transparency. Better safe than sorry!
54 | return alpha >= 3 ? PNG_A : PNG;
55 | }
56 |
57 | // GIF from first 3 bytes.
58 | if (firstFourBytes >> 8 == GIF_HEADER) {
59 | return GIF;
60 | }
61 |
62 | // WebP (reads up to 21 bytes). See https://developers.google.com/speed/webp/docs/riff_container
63 | // for details.
64 | if (firstFourBytes != RIFF_HEADER) {
65 | return UNKNOWN;
66 | }
67 | // Bytes 4 - 7 contain length information. Skip these.
68 | reader.skip(4);
69 | final int thirdFourBytes =
70 | (reader.getUInt16() << 16 & 0xFFFF0000) | (reader.getUInt16() & 0xFFFF);
71 | if (thirdFourBytes != WEBP_HEADER) {
72 | return UNKNOWN;
73 | }
74 | final int fourthFourBytes =
75 | (reader.getUInt16() << 16 & 0xFFFF0000) | (reader.getUInt16() & 0xFFFF);
76 | if ((fourthFourBytes & VP8_HEADER_MASK) != VP8_HEADER) {
77 | return UNKNOWN;
78 | }
79 | if ((fourthFourBytes & VP8_HEADER_TYPE_MASK) == VP8_HEADER_TYPE_EXTENDED) {
80 | // Skip some more length bytes and check for transparency/alpha flag.
81 | reader.skip(4);
82 | return (reader.getByte() & WEBP_EXTENDED_ALPHA_FLAG) != 0 ? ImageType.WEBP_A : ImageType.WEBP;
83 | }
84 | if ((fourthFourBytes & VP8_HEADER_TYPE_MASK) == VP8_HEADER_TYPE_LOSSLESS) {
85 | // See chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
86 | // for more info.
87 | reader.skip(4);
88 | return (reader.getByte() & WEBP_LOSSLESS_ALPHA_FLAG) != 0 ? ImageType.WEBP_A : ImageType.WEBP;
89 | }
90 | is.close();
91 | return ImageType.WEBP;
92 | }
93 | private interface Reader {
94 | int getUInt16() throws IOException;
95 | short getUInt8() throws IOException;
96 | long skip(long total) throws IOException;
97 | int read(byte[] buffer, int byteCount) throws IOException;
98 | int getByte() throws IOException;
99 | }
100 | private static final class StreamReader implements Reader {
101 | private final InputStream is;
102 |
103 | // Motorola / big endian byte order.
104 | StreamReader(InputStream is) {
105 | this.is = is;
106 | }
107 |
108 | @Override
109 | public int getUInt16() throws IOException {
110 | return (is.read() << 8 & 0xFF00) | (is.read() & 0xFF);
111 | }
112 |
113 | @Override
114 | public short getUInt8() throws IOException {
115 | return (short) (is.read() & 0xFF);
116 | }
117 |
118 | @Override
119 | public long skip(long total) throws IOException {
120 | if (total < 0) {
121 | return 0;
122 | }
123 |
124 | long toSkip = total;
125 | while (toSkip > 0) {
126 | long skipped = is.skip(toSkip);
127 | if (skipped > 0) {
128 | toSkip -= skipped;
129 | } else {
130 | // Skip has no specific contract as to what happens when you reach the end of
131 | // the stream. To differentiate between temporarily not having more data and
132 | // having finished the stream, we read a single byte when we fail to skip any
133 | // amount of data.
134 | int testEofByte = is.read();
135 | if (testEofByte == -1) {
136 | break;
137 | } else {
138 | toSkip--;
139 | }
140 | }
141 | }
142 | return total - toSkip;
143 | }
144 |
145 | @Override
146 | public int read(byte[] buffer, int byteCount) throws IOException {
147 | int toRead = byteCount;
148 | int read;
149 | while (toRead > 0 && ((read = is.read(buffer, byteCount - toRead, toRead)) != -1)) {
150 | toRead -= read;
151 | }
152 | return byteCount - toRead;
153 | }
154 |
155 | @Override
156 | public int getByte() throws IOException {
157 | return is.read();
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/util/KeyboardUtils.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.util;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.res.Resources;
6 | import android.graphics.Rect;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.view.ViewTreeObserver;
10 | import android.view.WindowManager;
11 | import android.view.inputmethod.InputMethodManager;
12 | import android.widget.FrameLayout;
13 |
14 | /**
15 | * Description:
16 | * Create by dance, at 2018/12/17
17 | */
18 | public final class KeyboardUtils {
19 |
20 | private static int sDecorViewInvisibleHeightPre;
21 | private static ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener;
22 | private static OnSoftInputChangedListener onSoftInputChangedListener;
23 |
24 | private KeyboardUtils() {
25 | throw new UnsupportedOperationException("u can't instantiate me...");
26 | }
27 |
28 | private static int sDecorViewDelta = 0;
29 |
30 | private static int getDecorViewInvisibleHeight(final Activity activity) {
31 | final View decorView = activity.getWindow().getDecorView();
32 | if (decorView == null) return sDecorViewInvisibleHeightPre;
33 | final Rect outRect = new Rect();
34 | decorView.getWindowVisibleDisplayFrame(outRect);
35 | int delta = Math.abs(decorView.getBottom() - outRect.bottom);
36 | if (delta <= getNavBarHeight()) {
37 | sDecorViewDelta = delta;
38 | return 0;
39 | }
40 | return delta - sDecorViewDelta;
41 | }
42 |
43 | /**
44 | * Register soft input changed listener.
45 | *
46 | * @param activity The activity.
47 | * @param listener The soft input changed listener.
48 | */
49 | public static void registerSoftInputChangedListener(final Activity activity, final OnSoftInputChangedListener listener) {
50 | final int flags = activity.getWindow().getAttributes().flags;
51 | if ((flags & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0) {
52 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
53 | }
54 | final FrameLayout contentView = activity.findViewById(android.R.id.content);
55 | sDecorViewInvisibleHeightPre = getDecorViewInvisibleHeight(activity);
56 | onSoftInputChangedListener = listener;
57 | onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
58 | @Override
59 | public void onGlobalLayout() {
60 | if (onSoftInputChangedListener != null) {
61 | int height = getDecorViewInvisibleHeight(activity);
62 | if (sDecorViewInvisibleHeightPre != height) {
63 | onSoftInputChangedListener.onSoftInputChanged(height);
64 | sDecorViewInvisibleHeightPre = height;
65 | }
66 | }
67 | }
68 | };
69 | contentView.getViewTreeObserver()
70 | .addOnGlobalLayoutListener(onGlobalLayoutListener);
71 | }
72 |
73 | public static void removeLayoutChangeListener(View decorView){
74 | View contentView = decorView.findViewById(android.R.id.content);
75 | contentView.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayoutListener);
76 | onGlobalLayoutListener = null;
77 | onSoftInputChangedListener = null;
78 | }
79 |
80 | private static int getNavBarHeight() {
81 | Resources res = Resources.getSystem();
82 | int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
83 | if (resourceId != 0) {
84 | return res.getDimensionPixelSize(resourceId);
85 | } else {
86 | return 0;
87 | }
88 | }
89 |
90 | public static void showSoftInput(View view) {
91 | InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
92 | imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
93 | }
94 |
95 | public static void hideSoftInput(View view) {
96 | InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
97 | imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
98 | }
99 |
100 | public interface OnSoftInputChangedListener {
101 | void onSoftInputChanged(int height);
102 | }
103 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/widget/BlankView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.RectF;
8 | import android.util.AttributeSet;
9 | import android.util.Log;
10 | import android.view.View;
11 |
12 | /**
13 | * Description: 大图浏览弹窗显示后的占位View
14 | * Create by lxj, at 2019/2/2
15 | */
16 | public class BlankView extends View {
17 | public BlankView(Context context) {
18 | super(context);
19 | }
20 |
21 | public BlankView(Context context, AttributeSet attrs) {
22 | super(context, attrs);
23 | init();
24 | }
25 |
26 | public BlankView(Context context, AttributeSet attrs, int defStyleAttr) {
27 | super(context, attrs, defStyleAttr);
28 | init();
29 | }
30 |
31 | private Paint paint = new Paint();
32 | private RectF rect = null;
33 | public int radius = 0;
34 | public int color = Color.WHITE;
35 | public int strokeColor = Color.parseColor("#DDDDDD");
36 |
37 | private void init() {
38 | paint.setAntiAlias(true);
39 | paint.setStrokeWidth(1);
40 | }
41 |
42 | @Override
43 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
44 | super.onSizeChanged(w, h, oldw, oldh);
45 | rect = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
46 | }
47 |
48 | @Override
49 | protected void onDraw(Canvas canvas) {
50 | super.onDraw(canvas);
51 | paint.setColor(color);
52 | canvas.drawRoundRect(rect, radius, radius, paint);
53 |
54 | paint.setStyle(Paint.Style.STROKE);
55 | paint.setColor(strokeColor);
56 | canvas.drawRoundRect(rect, radius, radius, paint);
57 | paint.setStyle(Paint.Style.FILL);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/widget/CheckView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 |
11 | import com.lxj.xpopup.util.XPopupUtils;
12 |
13 | /**
14 | * Description: 对勾View
15 | * Create by dance, at 2018/12/21
16 | */
17 | public class CheckView extends View {
18 | Paint paint;
19 | int color = Color.TRANSPARENT;
20 | public CheckView(Context context) {
21 | this(context, null);
22 | }
23 |
24 | public CheckView(Context context, AttributeSet attrs) {
25 | this(context, attrs, 0);
26 | }
27 |
28 | public CheckView(Context context, AttributeSet attrs, int defStyleAttr) {
29 | super(context, attrs, defStyleAttr);
30 | paint = new Paint(Paint.ANTI_ALIAS_FLAG);
31 | paint.setStrokeWidth(XPopupUtils.dp2px(context, 2));
32 | paint.setStyle(Paint.Style.STROKE);
33 | }
34 |
35 | /**
36 | * 设置对勾View
37 | * @param color
38 | */
39 | public void setColor(int color){
40 | this.color = color;
41 | paint.setColor(color);
42 | postInvalidate();
43 | }
44 |
45 | Path path = new Path();
46 | @Override
47 | protected void onDraw(Canvas canvas) {
48 | super.onDraw(canvas);
49 | if(color==Color.TRANSPARENT)return;
50 | // first part
51 | path.moveTo(getMeasuredWidth()/4, getMeasuredHeight()/2);
52 | path.lineTo(getMeasuredWidth()/2 , getMeasuredHeight()*3/4);
53 | // second part
54 | path.lineTo(getMeasuredWidth(), getMeasuredHeight()/4);
55 | canvas.drawPath(path, paint);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/widget/HackyViewPager.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.widget;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.view.ViewPager;
7 | import android.util.AttributeSet;
8 | import android.util.Log;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 |
12 | import com.lxj.xpopup.photoview.PhotoView;
13 |
14 | /**
15 | * see issues for PhotoView: https://github.com/chrisbanes/PhotoView
16 | */
17 | public class HackyViewPager extends ViewPager {
18 | public HackyViewPager(@NonNull Context context) {
19 | super(context);
20 | }
21 |
22 | public HackyViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
23 | super(context, attrs);
24 | }
25 | @Override
26 | public boolean onInterceptTouchEvent(MotionEvent ev) {
27 | try {
28 | return super.onInterceptTouchEvent(ev);
29 | } catch (IllegalArgumentException e) {
30 | //uncomment if you really want to see these errors
31 | //e.printStackTrace();
32 | return false;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/widget/LoadingView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.widget;
2 |
3 | import android.animation.ArgbEvaluator;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 |
11 | import com.lxj.xpopup.util.XPopupUtils;
12 |
13 | /**
14 | * Description: 加载View
15 | * Create by dance, at 2018/12/18
16 | */
17 | public class LoadingView extends View {
18 | private Paint paint;
19 | private float radius;
20 | private float radiusOffset;
21 | // 不是固定不变的,当width为30dp时,它为2dp,当宽度变大,这个也会相应的变大
22 | private float stokeWidth = 2f;
23 | private ArgbEvaluator argbEvaluator = new ArgbEvaluator();
24 | private int startColor = Color.parseColor("#CCCCCC");
25 | private int endColor = Color.parseColor("#333333");
26 | int lineCount = 12; // 共12条线
27 | float avgAngle = 360f / lineCount;
28 | int time = 0; // 重复次数
29 | float centerX, centerY; // 中心x,y
30 |
31 | public LoadingView(Context context) {
32 | this(context, null);
33 | }
34 |
35 | public LoadingView(Context context, AttributeSet attrs) {
36 | this(context, attrs, 0);
37 | }
38 |
39 | public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
40 | super(context, attrs, defStyleAttr);
41 | paint = new Paint(Paint.ANTI_ALIAS_FLAG);
42 | stokeWidth = XPopupUtils.dp2px(context, stokeWidth);
43 | paint.setStrokeWidth(stokeWidth);
44 | }
45 |
46 | @Override
47 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
48 | super.onSizeChanged(w, h, oldw, oldh);
49 | radius = getMeasuredWidth() / 2;
50 | radiusOffset = radius / 2.5f;
51 |
52 | centerX = getMeasuredWidth() / 2;
53 | centerY = getMeasuredHeight() / 2;
54 |
55 | stokeWidth *= getMeasuredWidth() * 1f / XPopupUtils.dp2px(getContext(), 30);
56 | paint.setStrokeWidth(stokeWidth);
57 | }
58 |
59 | @Override
60 | protected void onDraw(final Canvas canvas) {
61 | // 1 2 3 4 5
62 | // 2 3 4 5 1
63 | // 3 4 5 1 2
64 | // ...
65 | for (int i = lineCount - 1; i >= 0; i--) {
66 | int temp = Math.abs(i + time) % lineCount;
67 | float fraction = (temp + 1) * 1f / lineCount;
68 | int color = (int) argbEvaluator.evaluate(fraction, startColor, endColor);
69 | paint.setColor(color);
70 |
71 | float startX = centerX + radiusOffset;
72 | float endX = startX + radius / 3f;
73 | canvas.drawLine(startX, centerY, endX, centerY, paint);
74 | // 线的两端画个点,看着圆滑
75 | canvas.drawCircle(startX, centerY, stokeWidth / 2, paint);
76 | canvas.drawCircle(endX, centerY, stokeWidth / 2, paint);
77 | canvas.rotate(avgAngle, centerX, centerY);
78 | }
79 | postDelayed(increaseTask, 80);
80 | }
81 |
82 | private Runnable increaseTask = new Runnable() {
83 | @Override
84 | public void run() {
85 | time++;
86 | invalidate();
87 | }
88 | };
89 |
90 | @Override
91 | protected void onDetachedFromWindow() {
92 | super.onDetachedFromWindow();
93 | removeCallbacks(increaseTask);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/widget/PartShadowContainer.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.graphics.Rect;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.util.AttributeSet;
9 | import android.util.Log;
10 | import android.view.Gravity;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 | import android.view.ViewConfiguration;
14 | import android.widget.FrameLayout;
15 |
16 | import com.lxj.xpopup.interfaces.OnClickOutsideListener;
17 | import com.lxj.xpopup.util.XPopupUtils;
18 |
19 | /**
20 | * Description:
21 | * Create by dance, at 2019/1/10
22 | */
23 | public class PartShadowContainer extends FrameLayout {
24 | public boolean isDismissOnTouchOutside = true;
25 |
26 | public PartShadowContainer(@NonNull Context context) {
27 | super(context);
28 | }
29 |
30 | public PartShadowContainer(@NonNull Context context, @Nullable AttributeSet attrs) {
31 | this(context, attrs, 0);
32 | }
33 |
34 | public PartShadowContainer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
35 | super(context, attrs, defStyleAttr);
36 | }
37 |
38 | private float x, y;
39 | private long downTime;
40 |
41 | @Override
42 | public boolean onTouchEvent(MotionEvent event) {
43 | // 计算implView的Rect
44 | View implView = getChildAt(0);
45 | int[] location = new int[2];
46 | implView.getLocationInWindow(location);
47 | Rect implViewRect = new Rect(location[0], location[1], location[0] + implView.getMeasuredWidth() - (int)getTranslationY(),
48 | location[1] + implView.getMeasuredHeight() - (int)getTranslationY());
49 | if (!XPopupUtils.isInRect(event.getX(), event.getY(), implViewRect)) {
50 | switch (event.getAction()) {
51 | case MotionEvent.ACTION_DOWN:
52 | x = event.getX();
53 | y = event.getY();
54 | downTime = System.currentTimeMillis();
55 | break;
56 | case MotionEvent.ACTION_UP:
57 | float dx = event.getX() - x;
58 | float dy = event.getY() - y;
59 | float distance = (float) Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
60 | if (distance < ViewConfiguration.get(getContext()).getScaledTouchSlop() && (System.currentTimeMillis() - downTime) < 350) {
61 | if (isDismissOnTouchOutside) {
62 | if (listener != null) listener.onClickOutside();
63 | }
64 | }
65 | x = 0;
66 | y = 0;
67 | downTime = 0;
68 | break;
69 | }
70 | }
71 | return true;
72 | }
73 |
74 | private OnClickOutsideListener listener;
75 |
76 | public void setOnClickOutsideListener(OnClickOutsideListener listener) {
77 | this.listener = listener;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lxj/xpopup/widget/VerticalRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.lxj.xpopup.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.RectF;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.support.annotation.NonNull;
10 | import android.support.annotation.Nullable;
11 | import android.support.v7.widget.DividerItemDecoration;
12 | import android.support.v7.widget.LinearLayoutManager;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.util.AttributeSet;
15 |
16 | import com.lxj.xpopup.R;
17 |
18 | /**
19 | * Description:
20 | * Create by dance, at 2018/12/12
21 | */
22 | public class VerticalRecyclerView extends RecyclerView {
23 | public VerticalRecyclerView(@NonNull Context context) {
24 | this(context, null);
25 | }
26 |
27 | public VerticalRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
28 | this(context, attrs, 0);
29 | }
30 |
31 | public VerticalRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
32 | super(context, attrs, defStyle);
33 | setLayoutManager(new LinearLayoutManager(getContext()));
34 | DividerItemDecoration decoration = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);
35 |
36 | decoration.setDrawable(new ColorDrawable(getResources().getColor(R.color._xpopup_list_divider)));
37 | addItemDecoration(decoration);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/_xpopup_round3_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/_xpopup_round3_dark_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/_xpopup_shadow.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/library/src/main/res/drawable/_xpopup_shadow.9.png
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_adapter_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
27 |
28 |
32 |
33 |
36 |
37 |
43 |
44 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_attach_impl_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_attach_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_bottom_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_center_impl_confirm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
25 |
26 |
35 |
36 |
41 |
53 |
54 |
65 |
66 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_center_impl_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
20 |
21 |
22 |
23 |
28 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_center_impl_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_center_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_drawer_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_image_viewer_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
22 |
23 |
24 |
25 |
35 |
36 |
47 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/_xpopup_part_shadow_popup_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #dedede
4 | #111111
5 | #333333
6 |
--------------------------------------------------------------------------------
/library/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/screenshot/bottom_edit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/bottom_edit.gif
--------------------------------------------------------------------------------
/screenshot/comment_edit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/comment_edit.gif
--------------------------------------------------------------------------------
/screenshot/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/download.png
--------------------------------------------------------------------------------
/screenshot/fullscreen.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/fullscreen.gif
--------------------------------------------------------------------------------
/screenshot/horizontal_attach.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/horizontal_attach.gif
--------------------------------------------------------------------------------
/screenshot/image_viewer1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/image_viewer1.gif
--------------------------------------------------------------------------------
/screenshot/image_viewer2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/image_viewer2.gif
--------------------------------------------------------------------------------
/screenshot/image_viewer3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/image_viewer3.gif
--------------------------------------------------------------------------------
/screenshot/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/logo.png
--------------------------------------------------------------------------------
/screenshot/preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview.gif
--------------------------------------------------------------------------------
/screenshot/preview2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview2.gif
--------------------------------------------------------------------------------
/screenshot/preview3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview3.gif
--------------------------------------------------------------------------------
/screenshot/preview4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview4.gif
--------------------------------------------------------------------------------
/screenshot/preview_attach.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview_attach.gif
--------------------------------------------------------------------------------
/screenshot/preview_bottom.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview_bottom.gif
--------------------------------------------------------------------------------
/screenshot/preview_drawer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview_drawer.gif
--------------------------------------------------------------------------------
/screenshot/preview_part.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/preview_part.gif
--------------------------------------------------------------------------------
/screenshot/qqgroup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/screenshot/qqgroup.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library'
2 |
--------------------------------------------------------------------------------
/xpopup.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiann/XPopup/6233fc278b3c8fc42649b1f2f42fd785bb67cccc/xpopup.jks
--------------------------------------------------------------------------------