MVPArms框架自动生成MVP及Dagger2相关文件解决方案 第二代模版已经开源到 https://github.com/JessYanCoding/MVPArmsTemplate ,一键生成所有文件 (设置)Setting -> Editor -> File and Code Templates -> Files 然后点击左上角绿色的+号 下面有7个Template,将分隔符上Name: 后的字符复制到Name输入框里,将分隔符里的内容复制进下面的大输入框,复制完后在继续点+ 创建下一个,重复之前的操作,一共创建7个Template,点击右下角的ok按钮,现在在对应的包下点鼠标右键New选择项里就有刚才创建的 Template了,点击对应Template,在输入框中输入名字就可以创建对应的文件 再按照Contract->Model->Presenter->Activity->Module->Component的顺序在对应包下构建这6个模版,名字必须一样,这下 对应页面的Dagger和Mvp类即自动生成了,就可以专注写逻辑了 以下模版可以根据需求做相应修改 Name: Activity -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import android.content.Intent; import androidx.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import com.jess.arms.base.BaseActivity; import com.jess.arms.utils.ArmsUtils; import static com.jess.arms.utils.Preconditions.checkNotNull; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") public class ${NAME}Activity extends BaseActivity<${NAME}Presenter> implements ${NAME}Contract.View { @Override public void setupActivityComponent(AppComponent appComponent) { Dagger${NAME}Component .builder() .appComponent(appComponent) .${NAME}Module(new ${NAME}Module(this)) //请将${NAME}Module()第一个首字母改为小写 .build() .inject(this); } @Override public int initView(Bundle savedInstanceState) { return 0; } @Override public void initData(Bundle savedInstanceState) { } @Override public void showLoading() { } @Override public void hideLoading() { } @Override public void showMessage(@NonNull String message) { checkNotNull(message); ArmsUtils.snackbarText(message); } @Override public void launchActivity(@NonNull Intent intent) { checkNotNull(intent); ArmsUtils.startActivity(intent); } @Override public void killMyself() { finish(); } } -------------------------------------------------------------------------------------- Name: Component -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import com.jess.arms.di.scope.ActivityScope; import dagger.Component; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") @ActivityScope @Component(modules = ${NAME}Module.class,dependencies = AppComponent.class) public interface ${NAME}Component { void inject(${NAME}Activity activity); } -------------------------------------------------------------------------------------- Name: Contract -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import com.jess.arms.mvp.IView; import com.jess.arms.mvp.IModel; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") public interface ${NAME}Contract { //对于经常使用的关于UI的方法可以定义到IView中,如显示隐藏进度条,和显示文字消息 interface View extends IView { } //Model层定义接口,外部只需关心Model返回的数据,无需关心内部细节,即是否使用缓存 interface Model extends IModel{ } } -------------------------------------------------------------------------------------- Name: Fragment -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import android.content.Intent; import android.os.Bundle; import androidx.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import com.jess.arms.base.BaseFragment import com.jess.arms.utils.ArmsUtils; import butterknife.Bind; import static com.jess.arms.utils.Preconditions.checkNotNull; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") public class ${NAME}Fragment extends BaseFragment<${NAME}Presenter> implements ${NAME}Contract.View{ public static ${NAME}Fragment newInstance() { ${NAME}Fragment fragment = new ${NAME}Fragment(); return fragment; } @Override public void setupFragmentComponent(AppComponent appComponent) { Dagger${NAME}Component .builder() .appComponent(appComponent) .${NAME}Module(new ${NAME}Module(this))//请将${NAME}Module()第一个首字母改为小写 .build() .inject(this); } @Override public View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(layout_id, container, false); } @Override public void initData(Bundle savedInstanceState) { } /** * 此方法是让外部调用使fragment做一些操作的,比如说外部的activity想让fragment对象执行一些方法, * 建议在有多个需要让外界调用的方法时,统一传Message,通过what字段,来区分不同的方法,在setData * 方法中就可以switch做不同的操作,这样就可以用统一的入口方法做不同的事 * * 使用此方法时请注意调用时fragment的生命周期,如果调用此setData方法时onCreate还没执行 * setData里却调用了presenter的方法时,是会报空的,因为dagger注入是在onCreated方法中执行的,然后才创建的presenter * 如果要做一些初始化操作,可以不必让外部调setData,在initData中初始化就可以了 * * @param data */ @Override public void setData(Object data) { } @Override public void showLoading() { } @Override public void hideLoading() { } @Override public void showMessage(@NonNull String message) { checkNotNull(message); ArmsUtils.snackbarText(message); } @Override public void launchActivity(@NonNull Intent intent) { checkNotNull(intent); ArmsUtils.startActivity(intent); } @Override public void killMyself() { } } -------------------------------------------------------------------------------------- Name: Model -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import android.app.Application; import com.google.gson.Gson; import com.jess.arms.integration.IRepositoryManager; import com.jess.arms.mvp.BaseModel; import static com.jess.arms.utils.Preconditions.checkNotNull; import com.jess.arms.di.scope.ActivityScope; import javax.inject.Inject; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") @ActivityScope public class ${NAME}Model extends BaseModel implements ${NAME}Contract.Model{ private Gson mGson; private Application mApplication; @Inject public ${NAME}Model(IRepositoryManager repositoryManager, Gson gson, Application application) { super(repositoryManager); this.mGson = gson; this.mApplication = application; } @Override public void onDestroy() { super.onDestroy(); this.mGson = null; this.mApplication = null; } } -------------------------------------------------------------------------------------- Name: Module -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import com.google.gson.Gson; import android.app.Application; import com.jess.arms.di.scope.ActivityScope; import dagger.Module; import dagger.Provides; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") @Module public class ${NAME}Module { private ${NAME}Contract.View view; /** * 构建${NAME}Module时,将View的实现类传进来,这样就可以提供View的实现类给presenter * @param view */ public ${NAME}Module(${NAME}Contract.View view) { this.view = view; } @ActivityScope @Provides ${NAME}Contract.View provide${NAME}View(){ return this.view; } @ActivityScope @Provides ${NAME}Contract.Model provide${NAME}Model(${NAME}Model model){ return model; } } -------------------------------------------------------------------------------------- Name: Presenter -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import android.app.Application; import com.jess.arms.integration.AppManager; import com.jess.arms.di.scope.ActivityScope; import com.jess.arms.mvp.BasePresenter; import com.jess.arms.http.imageloader.ImageLoader; import me.jessyan.rxerrorhandler.core.RxErrorHandler; import javax.inject.Inject; /** * 通过Template生成对应页面的MVP和Dagger代码,请注意输入框中输入的名字必须相同 * 由于每个项目包结构都不一定相同,所以每生成一个文件需要自己导入import包名,可以在设置中设置自动导入包名 * 请在对应包下按以下顺序生成对应代码,Contract->Model->Presenter->Activity->Module->Component * 因为生成Activity时,Module和Component还没生成,但是Activity中有它们的引用,所以会报错,但是不用理会 * 继续将Module和Component生成完后,编译一下项目再回到Activity,按提示修改一个方法名即可 * 如果想生成Fragment的相关文件,则将上面构建顺序中的Activity换为Fragment,并将Component中inject方法的参数改为此Fragment */ #parse("File Header.java") @ActivityScope public class ${NAME}Presenter extends BasePresenter<${NAME}Contract.Model, ${NAME}Contract.View> { private RxErrorHandler mErrorHandler; private Application mApplication; private ImageLoader mImageLoader; private AppManager mAppManager; @Inject public ${NAME}Presenter (${NAME}Contract.Model model, ${NAME}Contract.View rootView , RxErrorHandler handler, Application application , ImageLoader imageLoader, AppManager appManager) { super(model, rootView); this.mErrorHandler = handler; this.mApplication = application; this.mImageLoader = imageLoader; this.mAppManager = appManager; } @Override public void onDestroy() { super.onDestroy(); this.mErrorHandler = null; this.mAppManager = null; this.mImageLoader = null; this.mApplication = null; } } -------------------------------------------------------------------------------------- Name: AutoView -------------------------------------------------------------------------------------- #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import android.content.Context; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.ViewGroup; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * 此Template用于生成AutoLayout需要的的Auto系列View,如需要使ScrollView适配,使用此Template输入ScrollView,即可生成 * AutoScrollView,使用此View即可自适应 * Created by jess on 16/4/14. */ public class Auto${NAME} extends ${NAME} { private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public Auto${NAME}(Context context) { super(context); } public Auto${NAME}(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public Auto${NAME}(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) mHelper.adjustChildren(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } public static class LayoutParams extends ${NAME}.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } } --------------------------------------------------------------------------------------