Repository: liys666666/DoubleClick Branch: master Commit: 1072281f1793 Files: 60 Total size: 67.9 KB Directory structure: gitextract_6gmwq0dw/ ├── .gitignore ├── .idea/ │ ├── codeStyles/ │ │ └── Project.xml │ ├── gradle.xml │ ├── misc.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── README.md ├── README1.0.4.md ├── README2.0.6.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── liys/ │ │ └── doubleclickdemo/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── liys/ │ │ │ └── doubleclickdemo/ │ │ │ ├── AppApplication.java │ │ │ ├── LogUtil.java │ │ │ ├── LoginClickListener.java │ │ │ ├── MainActivity.java │ │ │ ├── UnifiedDoubleClick.java │ │ │ ├── UnifiedDoubleClick2.java │ │ │ └── fragment/ │ │ │ ├── MainActivity2.java │ │ │ ├── MyFragment.java │ │ │ └── MyFragment2.java │ │ └── res/ │ │ ├── drawable/ │ │ │ └── ic_launcher_background.xml │ │ ├── drawable-v24/ │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ ├── activity_main2.xml │ │ │ ├── fragment_my.xml │ │ │ └── fragment_my2.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── liys/ │ └── doubleclickdemo/ │ └── ExampleUnitTest.java ├── build.gradle ├── doubleclicklibrary/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── liys/ │ │ └── doubleclicklibrary/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── liys/ │ │ │ └── doubleclicklibrary/ │ │ │ ├── DoubleClickHelper.java │ │ │ ├── annotation/ │ │ │ │ ├── AAddDoubleClick.java │ │ │ │ ├── ACancelActivity.java │ │ │ │ ├── AClickListener.java │ │ │ │ └── helper/ │ │ │ │ └── AnnotationHelper.java │ │ │ ├── aspect/ │ │ │ │ ├── AspectDoubleClick.java │ │ │ │ └── Attrs.java │ │ │ ├── hook/ │ │ │ │ ├── BaseHookView.java │ │ │ │ ├── HookOnClickListener.java │ │ │ │ └── IHookView.java │ │ │ └── listener/ │ │ │ └── IOnClickListener.java │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ └── test/ │ └── java/ │ └── com/ │ └── liys/ │ └── doubleclicklibrary/ │ └── ExampleUnitTest.java ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/caches/build_file_checksums.ser /.idea/libraries /.idea/modules.xml /.idea/workspace.xml .DS_Store /build /captures .externalNativeBuild ================================================ FILE: .idea/codeStyles/Project.xml ================================================ ================================================ FILE: .idea/gradle.xml ================================================ ================================================ FILE: .idea/misc.xml ================================================ ================================================ FILE: .idea/runConfigurations.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: README.md ================================================ # DoubleClick 简书: [DoubleClick---3.0版本](https://www.jianshu.com/p/daac21821c43) [DoubleClick---2.0版本](https://www.jianshu.com/p/df0ef3866cc1) [DoubleClick---1.0版本](https://www.jianshu.com/p/7f3e5c8b8643) **V3.0 的使用方法:** **1.导入:** ``` //项目根目录下,build.gradle buildscript { ... dependencies { classpath 'com.android.tools.build:gradle:3.2.0' classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8' //添加 } } allprojects { repositories { ... maven { url 'https://jitpack.io' } //添加 } } ``` ``` //app目录下build.gradle apply plugin: 'android-aspectjx' //添加 dependencies { implementation 'com.github.liys666666:DoubleClick:V3.0.0' //添加 } ``` 如果不需要额外处理的话, 到这里就结束了, 同一个按钮点击, 默认最小间隔时间是500毫秒. **2.添加自定义属性:** ``` public class AppApplication extends Application{ @Override public void onCreate() { super.onCreate(); DoubleClickHelper .getInstance() .delayTime(500) //间隔时间 .addAnnotationClass(UnifiedDoubleClick.class) //自定义属性, 可叠加 .addAnnotationClass(UnifiedDoubleClick2.class); } } ``` ``` public interface UnifiedDoubleClick{ //用户自定义接口 // >>>>>>>>>>>>>>>>>>>屏蔽DoubleClick的Activity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // @ACancelActivity(activitys = { // MainActivity.class, // }) // void cancelActivity(); // >>>>>>>>>>>>>>>>>>>单个view处理>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @AAddDoubleClick(activity = MainActivity.class, addIds = {R.id.btn1, R.id.btn2}, times = {0, 2000}) //点击的间隔时间 void mainActivity(); // >>>>>>>>>>>>>>>>>插入自定义clickListener>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @AClickListener(activity = MainActivity.class, lisenner = LoginClickListener.class, //自定义clickListener ids = {R.id.btn2}) void interceptMain(); } ``` ``` public class LoginClickListener implements IOnClickListener { public static boolean isLogin = false; @Override public boolean isNext(View v) { //判断登录逻辑 if(!isLogin){ LogUtil.d("未登录"); Toast.makeText(v.getContext(), "未登录", Toast.LENGTH_SHORT).show(); } return isLogin; } @Override public void after(View view) { //执行click后 } } ``` **扩展---可调用方法** ``` DoubleClickHelper.openAll(); //开启 DoubleClickHelper.closeAll(); //关闭 //(可选)用hook方式处理单个view, 时间会和上面的时间叠加, 一般使用场景: Activity只有个别按钮需要doubleClick DoubleClickHelper.hookView(View view, long delayTime); ``` # 三.历史版本: **V3.0.0:** 使用AOP的方式处理, 使用方式和2.0基本一样, 比2.0的方式性能更好. [V2.0版本](https://github.com/liys666666/DoubleClick/blob/master/README2.0.6.md). [V1.0版本](https://github.com/liys666666/DoubleClick/blob/master/README1.0.4.md) * 如果框架中存在不足或者有什么建议, 欢迎指出, 我这边会尽快处理, 让框架更完善, 希望这个框架能帮助更多人, 如果觉得好用, 欢迎star. ================================================ FILE: README1.0.4.md ================================================ # DoubleClick # 一. 基本使用 框架主要有两个功能(基本用法): **1. 无入侵解决按钮重复点击.** [使用方法](https://www.jianshu.com/p/7f3e5c8b8643) **2. onClick重复逻辑统一处理.** [使用方法](https://www.jianshu.com/p/b4038a2d68eb) **① 导入框架** ``` //项目根目录下,build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' } //添加 } } ``` ``` //app目录下build.gradle dependencies { implementation 'com.github.liys666666:DoubleClick:V1.0.4' //添加 } ``` **② 自定义的Application初始化即可** ``` public class AppApplication extends Application{ @Override public void onCreate() { super.onCreate(); ViewDoubleHelper.init(this); //默认时间:1秒 // ViewDoubleHelper.init(this, 2000); //自定义点击间隔时间(单位:毫秒) } } ``` # 二.扩展: **V.1.0.2(包含)以上** 1. onClick重复逻辑统一处理--添加新写法(可选): 建议先看基本用法: [onClick重复逻辑统一处理](https://www.jianshu.com/p/b4038a2d68eb) ``` public class MainActivity extends AppCompatActivity implements IAddCustomHookClick{ @Override public List getCustomHookList() { int[] ids = {R.id.btn1, R.id.btn2}; //需要处理的id List list = new ArrayList<>(); for (int i = 0; i < ids.length; i++) { //添加 list.add(new CustomHookBean(ids[i], new LoginClickListener())); } return list; } } ``` 2. 如果有更好的具体实现方法, 也可以自己实现, 具体做法, 其它不变, 在AppApplication是添加: ``` //连续重复点击多次, 自定义具体实现 // ViewDoubleHelper.setIViewDoubleClick(new IViewDoubleClick() { // @Override // public void hookActivityViews(Activity activity, long delayTime) { // //hook Activity内所有View // } // // @Override // public void hookResView(Activity activity, int viewResId, long delayTime) { // //根据ViewId hook对应的View // } // // @Override // public void hookView(Activity activity, View view, long delayTime) { // //hook对应的View // } // }); //onClick重复逻辑统一处理: 自定义具体实现 // ViewDoubleHelper.setICustomHookClick(new ICustomHookClick() { // @Override // public void hookResView(Activity activity, int viewResId, IOnClickListener iClickListener) { // // } // // @Override // public void hookView(Activity activity, View view, IOnClickListener iClickListener) { // // } // }); ``` # 三.历史版本: **V1.0.4:** 修复:版本兼容问题 **V1.0.3:** 修复bug: 每次pause返回, 都重复hookView **V1.0.2:** * ①.onClick重复逻辑统一处理使用IAddCustomHookClick处理, 添加自由扩展实现. * ②. 新增方法 ViewDoubleHelper.setIViewDoubleClick(IViewDoubleClick), ViewDoubleHelper.setICustomHookClick(ICustomHookClick); **V1.0.1:** 新增功能: onClick重复逻辑统一处理 **V1.0.0:** 新增功能: 无入侵解决按钮重复点击 ================================================ FILE: README2.0.6.md ================================================ # DoubleClick V2.0 的使用方法: 简书: https://www.jianshu.com/p/df0ef3866cc1 CSDN: https://blog.csdn.net/qq_33199629/article/details/101563232 **简单介绍:** ``` //项目根目录下,build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' } //添加 } } ``` ``` //app目录下build.gradle dependencies { implementation 'com.github.liys666666:DoubleClick:V2.0.6' //添加 } ``` ``` public class AppApplication extends Application{ @Override public void onCreate() { super.onCreate(); // ViewDoubleHelper.init(this); //默认时间:1秒 // ViewDoubleHelper.init(this, 500); //自定义点击间隔时间(单位:毫秒) ViewDoubleHelper.init(this, 1000, UnifiedDoubleClick.class); //自定义点击间隔时间(单位:毫秒) //单独设置, 不同的AnnotationClass可叠加(V2.0.5版本后可用) ViewDoubleHelper.addAnnotationClass(UnifiedDoubleClick2.class); } } ``` ``` public interface UnifiedDoubleClick{ //用户自定义接口 // >>>>>>>>>>>>>>>>>>>屏蔽DoubleClick的Activity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // @ACancelActivity(activitys = { // MainActivity.class, // }) // void cancelActivity(); // >>>>>>>>>>>>>>>>>>>单个view处理>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @AAddDoubleClick(activity = MainActivity.class, addIds = {R.id.btn1, R.id.btn2}, times = {0, 2000}) //点击的间隔时间 void mainActivity(); // >>>>>>>>>>>>>>>>>插入自定义clickListener>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @AClickListener(activity = MainActivity.class, lisenner = LoginClickListener.class, //自定义clickListener ids = {R.id.btn2}) void interceptMain(); } ``` ``` public class LoginClickListener extends BaseClickListener{ public static boolean isLogin = false; //模拟是否登陆 @Override public boolean isNext(View v) { //判断登录逻辑 (onClick前执行) return isLogin; //true继续执行onClick, false不再执行 } @Override public void after(View view) { //onClick后 执行 } } ``` **扩展---可调用方法** ``` //hook单个view(子View不会跟着变化) 例如: Recyclerview使用的话, itemView是不起作用的 ViewDoubleHelper.hookView(View view, long delayTime); hook单个view(所有子View会跟着一起变化) 例如: Recyclerview使用的话, itemView以及子控件全部有用 ViewDoubleHelper.hookChildViews(View view, long delayTime); //重新hook当前Activity ViewDoubleHelper.hookActivity(); //如果你有更好的实现方法, 也可以自己实现 ViewDoubleHelper.addIViewDoubleClick(IViewDoubleClick iHookView); ``` # 三.历史版本: **V2.0.6:** * 修复: * ViewDoubleHelper.hookChildViews() 不起作用 * ViewDoubleHelper.hookActivity()在onResume()前 调用不起作用. **V2.0.5:** * 优化: 问题描述:原来的注解只能在Application初始化时传一个类进去; * 问题1: 如果注解使用过多, 所有的注解都写在一个类里面, 不好管理. * 问题2: 在组件化架构中, 有个id无法在Application中获取. * 解决办法: 使用新增方法 ViewDoubleHelper.addAnnotationClass(annotationClass); 可设置多个 **V2.0.4:** * 修复: 动态加载View不起作用(包括自定义View, Fragment, RecyclerView中不起作用等等)。 **V2.0.2:** * 1. 修复兼容问题:注解android9.0不起作用. * 2. 手动重新hookActivity **V2.0.1:** * 1. 完全不需要在具体的Activity和Fragment加代码. * 2. 是否屏蔽hook、单个View处理, 自定义拦截器,全部使用接口注解处理. * 3. 单个View处理、自定义拦截器,兼容Fragment. [V1.0版本](https://github.com/liys666666/DoubleClick/blob/master/README1.0.4.md) * 如果框架中存在不足或者有什么建议, 欢迎指出, 我这边会尽快处理, 让框架更完善, 希望这个框架能帮助更多人, 如果觉得好用, 欢迎star. ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' apply plugin: 'android-aspectjx' android { compileSdkVersion 28 defaultConfig { applicationId "com.liys.doubleclickdemo" minSdkVersion 19 targetSdkVersion 28 versionCode 6 versionName "3.0.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation project(':doubleclicklibrary') } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: app/src/androidTest/java/com/liys/doubleclickdemo/ExampleInstrumentedTest.java ================================================ package com.liys.doubleclickdemo; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumented test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.liys.doubleclickdemo", appContext.getPackageName()); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/AppApplication.java ================================================ package com.liys.doubleclickdemo; import android.app.Application; import com.liys.doubleclicklibrary.DoubleClickHelper; /** * @Description: * @Author: liys * @CreateDate: 2019/8/22 11:01 * @UpdateUser: 更新者 * @UpdateDate: 2019/8/22 11:01 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class AppApplication extends Application{ @Override public void onCreate() { super.onCreate(); DoubleClickHelper .getInstance() .delayTime(500) //间隔时间 .addAnnotationClass(UnifiedDoubleClick.class) .addAnnotationClass(UnifiedDoubleClick2.class); } } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/LogUtil.java ================================================ package com.liys.doubleclickdemo; import android.util.Log; /** * @Description: 输出日志 * @Author: liys * @CreateDate: 2019/5/28 10:55 * @UpdateUser: 更新者 * @UpdateDate: 2019/5/28 10:55 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class LogUtil { //是否需要打印信息 public static boolean isDebug = true; //打印信息的标识 public static final String TAG = "66"; public static void e(String msg) { if (isDebug) Log.e(TAG, msg); } public static void d(String msg) { if (isDebug) Log.d(TAG, msg); } public static void i(String msg) { if (isDebug) Log.i(TAG, msg); } public static void w(String msg) { if (isDebug) Log.w(TAG, msg); } } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/LoginClickListener.java ================================================ package com.liys.doubleclickdemo; import android.view.View; import android.widget.Toast; import com.liys.doubleclicklibrary.listener.IOnClickListener; /** * @Description: * @Author: liys * @CreateDate: 2019/8/22 15:52 * @UpdateUser: 更新者 * @UpdateDate: 2019/11/23 22:52 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class LoginClickListener implements IOnClickListener { public static boolean isLogin = false; @Override public boolean isNext(View v) { //判断登录逻辑 if(!isLogin){ LogUtil.d("未登录"); Toast.makeText(v.getContext(), "未登录", Toast.LENGTH_SHORT).show(); } return isLogin; } @Override public void after(View view) { //执行click后 } } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/MainActivity.java ================================================ package com.liys.doubleclickdemo; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.liys.doubleclickdemo.fragment.MainActivity2; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ TextView tvHint; long num = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvHint = findViewById(R.id.tv_hint); findViewById(R.id.btn1).setOnClickListener(this); findViewById(R.id.btn2).setOnClickListener(this); findViewById(R.id.login).setOnClickListener(this); findViewById(R.id.logout).setOnClickListener(this); findViewById(R.id.start).setOnClickListener(this); // Log.d("66", "btn1="+R.id.btn1); // Log.d("66", "onCreate"); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn1: num++; tvHint.setText(num+""); break; case R.id.btn2: num--; tvHint.setText(num+""); break; case R.id.login: LoginClickListener.isLogin = true; Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show(); break; case R.id.logout: LoginClickListener.isLogin = false; Toast.makeText(this, "取消登录", Toast.LENGTH_SHORT).show(); break; case R.id.start: startActivity(new Intent(this, MainActivity2.class)); break; } } } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/UnifiedDoubleClick.java ================================================ package com.liys.doubleclickdemo; import com.liys.doubleclickdemo.fragment.MainActivity2; import com.liys.doubleclicklibrary.annotation.AAddDoubleClick; import com.liys.doubleclicklibrary.annotation.AClickListener; /** * @Description: 统一处理 DoubleClick * @Author: liys * @CreateDate: 2019/8/26 16:46 * @UpdateUser: 更新者 * @UpdateDate: 2019/8/26 16:46 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public interface UnifiedDoubleClick{ // >>>>>>>>>>>>>>>>>>>屏蔽DoubleClick的Activity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // @ACancelActivity(activitys = { // MainActivity.class, // }) // void cancelActivity(); // >>>>>>>>>>>>>>>>>>>单个view处理>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // @AAddDoubleClick(activity = MainActivity.class, // addIds = {R.id.btn1, R.id.btn2}, // times = {2000, 0}) // void mainActivity(); @AAddDoubleClick(activity = MainActivity2.class, addIds = {R.id.btn_add_fragment, R.id.btn_fragment}, times = {2000, 2000}) void mainActivity2(); // >>>>>>>>>>>>>>>>>自定义click拦截器>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @AClickListener(activity = MainActivity.class, lisenner = LoginClickListener.class, ids = {R.id.btn2}) void interceptMain(); @AClickListener(activity = MainActivity2.class, lisenner = LoginClickListener.class, ids = {R.id.btn_add_fragment, R.id.btn_fragment}) void interceptMain2(); } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/UnifiedDoubleClick2.java ================================================ package com.liys.doubleclickdemo; import com.liys.doubleclicklibrary.annotation.ACancelActivity; /** * @Description: 统一处理 DoubleClick * @Author: liys * @CreateDate: 2019/8/26 16:46 * @UpdateUser: 更新者 * @UpdateDate: 2019/8/26 16:46 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public interface UnifiedDoubleClick2 { // >>>>>>>>>>>>>>>>>>>屏蔽DoubleClick的Activity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @ACancelActivity(activitys = { MainActivity.class, }) void cancelActivity(); } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/fragment/MainActivity2.java ================================================ package com.liys.doubleclickdemo.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; import com.liys.doubleclickdemo.R; public class MainActivity2 extends AppCompatActivity implements OnClickListener{ ViewPager viewPage; TextView tvNum; int num = 0; MyFragment myFragment = new MyFragment(); MyFragment2 myFragment2 = new MyFragment2(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); viewPage = findViewById(R.id.viewPage); tvNum = findViewById(R.id.tv_num); findViewById(R.id.btn_add_fragment).setOnClickListener(this); findViewById(R.id.btn_add_fragment2).setOnClickListener(this); findViewById(R.id.btn_add).setOnClickListener(this); viewPage.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int i) { if(i==0){ return myFragment; } return myFragment2; } @Override public int getCount() { return 2; } }); } Fragment curFragment; @Override public void onClick(View v) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); switch (v.getId()){ case R.id.btn_add_fragment: // transaction.replace(R.id.myFragment, myFragment); // transaction.commit(); if(myFragment.isAdded()){ transaction .hide(myFragment2) .show(myFragment) .commit(); }else{ transaction .hide(myFragment2) .add(R.id.myFragment, myFragment) .show(myFragment) .commit(); } break; case R.id.btn_add_fragment2: if(myFragment2.isAdded()){ transaction .hide(myFragment) .show(myFragment2) .commit(); }else{ transaction .hide(myFragment) .add(R.id.myFragment, myFragment2) .show(myFragment2) .commit(); } break; case R.id.btn_fragment: num--; tvNum.setText(num+""); break; case R.id.btn_add: num++; tvNum.setText(num+""); break; } } } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/fragment/MyFragment.java ================================================ package com.liys.doubleclickdemo.fragment; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.liys.doubleclickdemo.R; /** * @Description: * @Author: liys * @CreateDate: 2019/8/28 13:45 * @UpdateUser: 更新者 * @UpdateDate: 2019/8/28 13:45 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class MyFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_my, container, false); view.findViewById(R.id.btn_fragment).setOnClickListener((View.OnClickListener)getActivity()); return view; } } ================================================ FILE: app/src/main/java/com/liys/doubleclickdemo/fragment/MyFragment2.java ================================================ package com.liys.doubleclickdemo.fragment; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.liys.doubleclickdemo.R; /** * @Description: * @Author: liys * @CreateDate: 2019/8/28 13:45 * @UpdateUser: 更新者 * @UpdateDate: 2019/8/28 13:45 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class MyFragment2 extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_my2, container, false); view.findViewById(R.id.btn_fragment).setOnClickListener((View.OnClickListener)getActivity()); return view; } } ================================================ FILE: app/src/main/res/drawable/ic_launcher_background.xml ================================================ ================================================ FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml ================================================ ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================