diff --git a/others/others/个人自评报告.xlsx b/others/others/个人自评报告.xlsx new file mode 100644 index 0000000..70f0626 Binary files /dev/null and b/others/others/个人自评报告.xlsx differ diff --git a/others/others/后台管理系统演示.mp4 b/others/others/后台管理系统演示.mp4 new file mode 100644 index 0000000..5aa224c Binary files /dev/null and b/others/others/后台管理系统演示.mp4 differ diff --git a/others/others/团队自评报告.xlsx b/others/others/团队自评报告.xlsx new file mode 100644 index 0000000..6464594 Binary files /dev/null and b/others/others/团队自评报告.xlsx differ diff --git a/others/others/客户端演示.mp4 b/others/others/客户端演示.mp4 new file mode 100644 index 0000000..c1735f0 Binary files /dev/null and b/others/others/客户端演示.mp4 differ diff --git a/others/others/宣传彩页.jpg b/others/others/宣传彩页.jpg new file mode 100644 index 0000000..89057d2 Binary files /dev/null and b/others/others/宣传彩页.jpg differ diff --git a/others/others/答辩.pptx b/others/others/答辩.pptx new file mode 100644 index 0000000..b8b4bb3 Binary files /dev/null and b/others/others/答辩.pptx differ diff --git a/src/weapon/app/src/androidTest/java/com/test/weapon/ExampleInstrumentedTest.java b/src/weapon/app/src/androidTest/java/com/test/weapon/ExampleInstrumentedTest.java new file mode 100644 index 0000000..8296ffe --- /dev/null +++ b/src/weapon/app/src/androidTest/java/com/test/weapon/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.test.weapon; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.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.getInstrumentation().getTargetContext(); + assertEquals("com.test.weapon", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/.DS_Store b/src/weapon/app/src/main/java/com/test/.DS_Store new file mode 100644 index 0000000..46ca0c2 Binary files /dev/null and b/src/weapon/app/src/main/java/com/test/.DS_Store differ diff --git a/src/weapon/app/src/main/java/com/test/weapon/Adapter/ChooseProductAdapter.java b/src/weapon/app/src/main/java/com/test/weapon/Adapter/ChooseProductAdapter.java new file mode 100644 index 0000000..8b899d0 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/Adapter/ChooseProductAdapter.java @@ -0,0 +1,43 @@ +package com.test.weapon.Adapter; + +import android.graphics.Bitmap; +import android.widget.CheckBox; + +import androidx.annotation.NonNull; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.test.weapon.R; +import com.test.weapon.bean.GetWeaponList; +import com.test.weapon.util.AppData; +import com.test.weapon.util.SmartImageView; + +public class ChooseProductAdapter extends BaseQuickAdapter { + + + public ChooseProductAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, GetWeaponList data) { + baseViewHolder.setText(R.id.tv_maybe_like_name,data.getName()); + baseViewHolder.getView(R.id.choose_cb); + CheckBox checkBox = baseViewHolder.getView(R.id.choose_cb); + checkBox.setChecked(data.isChoose()); + SmartImageView siv_maybe_like=baseViewHolder.getView(R.id.siv_maybe_like); + + siv_maybe_like.setImageUrl(AppData.PicAddress+data.getImgPath(), new SmartImageView.onCompleteListener() { + @Override + public void onSuccess(Bitmap bitmap) { + System.out.println("----------------------success"); + } + + @Override + public void onFail() { + System.out.println("----------------------failed"); + + } + }); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/Adapter/FixInAdvanceAdapter.java b/src/weapon/app/src/main/java/com/test/weapon/Adapter/FixInAdvanceAdapter.java new file mode 100644 index 0000000..654c69b --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/Adapter/FixInAdvanceAdapter.java @@ -0,0 +1,32 @@ +package com.test.weapon.Adapter; + +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.test.weapon.util.AppData; +import com.test.weapon.R; +import com.test.weapon.bean.GetWeaponList; + +public class FixInAdvanceAdapter extends BaseQuickAdapter { + + public FixInAdvanceAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, GetWeaponList fixInAdvanceBean) { + Glide.with(getContext()).load(AppData.PicAddress+fixInAdvanceBean.getImgPath()).into((ImageView) baseViewHolder.getView(R.id.img_url)); + baseViewHolder.setText(R.id.tv_name,fixInAdvanceBean.getName()); + baseViewHolder.setText(R.id.tv_desc,"子弹口径:"+fixInAdvanceBean.getBulletCaliber()+"mm\n弹夹容量:"+fixInAdvanceBean.getCartridgeCapacity()+"\n有效射程:"+fixInAdvanceBean.getEffectiveRange()); + if (fixInAdvanceBean.getIsLend()==1){ + baseViewHolder.setText(R.id.tv_lend,"续借"); + }else{ + baseViewHolder.setText(R.id.tv_lend,"借出"); + } + + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/Adapter/HistoryAdapter.java b/src/weapon/app/src/main/java/com/test/weapon/Adapter/HistoryAdapter.java new file mode 100644 index 0000000..703a335 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/Adapter/HistoryAdapter.java @@ -0,0 +1,38 @@ +package com.test.weapon.Adapter; + +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.test.weapon.R; +import com.test.weapon.api.ReturnWeaponListApi; +import com.test.weapon.util.AppData; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class HistoryAdapter extends BaseQuickAdapter { + + public HistoryAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, ReturnWeaponListApi.Bean fixInAdvanceBean) { + Glide.with(getContext()).load(AppData.PicAddress+fixInAdvanceBean.getWeaponry().getImgPath()).into((ImageView) baseViewHolder.getView(R.id.img_url)); + baseViewHolder.setText(R.id.tv_name,fixInAdvanceBean.getWeaponryName()); + baseViewHolder.setText(R.id.tv_name,fixInAdvanceBean.getWeaponryName()+"\n子弹口径:"+fixInAdvanceBean.getWeaponry().getBulletCaliber()+"mm\n弹夹容量:"+fixInAdvanceBean.getWeaponry().getCartridgeCapacity()+"\n有效射程:"+fixInAdvanceBean.getWeaponry().getEffectiveRange()); + + + + } + + public static String getDateToString(long milSecond) { + Date date = new Date(milSecond); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.format(date); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/Adapter/LocationAlarmAdapter.java b/src/weapon/app/src/main/java/com/test/weapon/Adapter/LocationAlarmAdapter.java new file mode 100644 index 0000000..b300806 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/Adapter/LocationAlarmAdapter.java @@ -0,0 +1,27 @@ +package com.test.weapon.Adapter; + +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.test.weapon.util.AppData; +import com.test.weapon.R; +import com.test.weapon.bean.GetWeaponList; + +public class LocationAlarmAdapter extends BaseQuickAdapter { + + public LocationAlarmAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, GetWeaponList fixInAdvanceBean) { + Glide.with(getContext()).load(AppData.PicAddress+fixInAdvanceBean.getImgPath()).into((ImageView) baseViewHolder.getView(R.id.img_url)); + baseViewHolder.setText(R.id.tv_name,fixInAdvanceBean.getName()+"已超出指定范围"); + baseViewHolder.setText(R.id.tv_desc,"子弹口径:"+fixInAdvanceBean.getBulletCaliber()+"mm\n弹夹容量:"+fixInAdvanceBean.getCartridgeCapacity()+"\n有效射程:"+fixInAdvanceBean.getEffectiveRange()); + + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/Adapter/RemindAdapter.java b/src/weapon/app/src/main/java/com/test/weapon/Adapter/RemindAdapter.java new file mode 100644 index 0000000..c8d6e40 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/Adapter/RemindAdapter.java @@ -0,0 +1,41 @@ +package com.test.weapon.Adapter; + +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.test.weapon.api.ReturnWeaponListApi; +import com.test.weapon.R; +import com.test.weapon.util.AppData; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class RemindAdapter extends BaseQuickAdapter { + + public RemindAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, ReturnWeaponListApi.Bean fixInAdvanceBean) { + Glide.with(getContext()).load(AppData.PicAddress+fixInAdvanceBean.getWeaponry().getImgPath()).into((ImageView) baseViewHolder.getView(R.id.img_url)); + baseViewHolder.setText(R.id.tv_name,fixInAdvanceBean.getWeaponryName()); + baseViewHolder.setText(R.id.tv_name,fixInAdvanceBean.getWeaponryName()+"\n子弹口径:"+fixInAdvanceBean.getWeaponry().getBulletCaliber()+"mm\n弹夹容量:"+fixInAdvanceBean.getWeaponry().getCartridgeCapacity()+"\n有效射程:"+fixInAdvanceBean.getWeaponry().getEffectiveRange()); + + baseViewHolder.setText(R.id.tv_time,"归还时间:"+getDateToString(fixInAdvanceBean.getReturnTime())); + baseViewHolder.setVisible(R.id.tv_return,fixInAdvanceBean.getReturnStatus()==0); + baseViewHolder.setVisible(R.id.img_warring,fixInAdvanceBean.getReturnTime() { + + + public SearchProductAdapter(int layoutResId) { + super(layoutResId); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, GetWeaponList data) { + baseViewHolder.setText(R.id.tv_maybe_like_name,data.getName()); + + baseViewHolder.setText(R.id.tv_desc,"子弹口径:"+data.getBulletCaliber()+"mm\n弹夹容量:"+data.getCartridgeCapacity()+"\n有效射程:"+data.getEffectiveRange()); + + SmartImageView siv_maybe_like=baseViewHolder.getView(R.id.siv_maybe_like); + + siv_maybe_like.setImageUrl(AppData.PicAddress+data.getImgPath(), new SmartImageView.onCompleteListener() { + @Override + public void onSuccess(Bitmap bitmap) { + System.out.println("----------------------success"); + } + + @Override + public void onFail() { + System.out.println("----------------------failed"); + + } + }); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/AppApplication.java b/src/weapon/app/src/main/java/com/test/weapon/AppApplication.java new file mode 100644 index 0000000..a393a82 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/AppApplication.java @@ -0,0 +1,57 @@ +package com.test.weapon; + +import android.app.Application; + +import androidx.annotation.NonNull; + +import com.hjq.http.EasyConfig; +import com.hjq.http.config.IRequestInterceptor; +import com.hjq.http.config.IRequestServer; +import com.hjq.http.model.HttpHeaders; +import com.hjq.http.model.HttpParams; +import com.hjq.http.request.HttpRequest; +import com.hjq.toast.Toaster; +import com.test.weapon.http.ReleaseServer; +import com.test.weapon.http.RequestHandler; + +import okhttp3.OkHttpClient; + + +public class AppApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + Toaster.init(this); + + + // 网络请求框架初始化 + IRequestServer server; + server = new ReleaseServer(); + + OkHttpClient okHttpClient = new OkHttpClient.Builder() + .build(); + + EasyConfig.with(okHttpClient) + // 是否打印日志 + .setLogEnabled(BuildConfig.DEBUG) + // 设置服务器配置(必须设置) + .setServer(server) + // 设置请求处理策略(必须设置) + .setHandler(new RequestHandler(this)) + // 设置请求参数拦截器 + .setInterceptor(new IRequestInterceptor() { + @Override + public void interceptArguments(@NonNull HttpRequest httpRequest, + @NonNull HttpParams params, + @NonNull HttpHeaders headers) { + } + }) + + // 设置请求重试次数 + .setRetryCount(1) + // 设置请求重试时间 + .setRetryTime(2000) + + .into(); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/BaseFragment.java b/src/weapon/app/src/main/java/com/test/weapon/BaseFragment.java new file mode 100644 index 0000000..bead9dd --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/BaseFragment.java @@ -0,0 +1,22 @@ +package com.test.weapon; + +import androidx.fragment.app.Fragment; + +import com.hjq.http.listener.OnHttpListener; +import com.hjq.toast.Toaster; +import com.test.weapon.http.HttpData; + + +public class BaseFragment extends Fragment implements OnHttpListener { + @Override + public void onSucceed(Object result) { + if (result instanceof HttpData) { + Toaster.show(((HttpData) result).getMessage()); + } + } + + @Override + public void onFail(Exception e) { + + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/ChooseActivity.java b/src/weapon/app/src/main/java/com/test/weapon/ChooseActivity.java new file mode 100644 index 0000000..f609f44 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/ChooseActivity.java @@ -0,0 +1,135 @@ +package com.test.weapon; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemChildClickListener; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.hjq.http.listener.OnHttpListener; +import com.test.weapon.Adapter.ChooseProductAdapter; +import com.test.weapon.Adapter.SearchProductAdapter; +import com.test.weapon.api.GetWeaponApi; +import com.test.weapon.bean.GetWeaponList; +import com.test.weapon.http.HttpData; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import es.dmoral.toasty.Toasty; + +public class ChooseActivity extends AppCompatActivity { + + private RecyclerView rvSearch; + private List dataSearch; + private ChooseProductAdapter adapter; + private TextView choose_success; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_choose); + initView(); + } + + private void initView(){ + findViewById(R.id.img_close).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + rvSearch=findViewById(R.id.rv_search); + choose_success=findViewById(R.id.choose_success); + adapter = new ChooseProductAdapter(R.layout.item_choose_products); + rvSearch.setLayoutManager(new LinearLayoutManager(ChooseActivity.this)); + rvSearch.setAdapter(adapter); + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + for (int i=0;i(); + Map map=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + EasyHttp.post(this) + .api(new GetWeaponApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(new OnHttpListener() { + + + @Override + public void onSucceed(Object o) { + + } + + @Override + public void onFail(Exception e) { + + } + }) { + + @Override + public void onSucceed(HttpData> result) { + dataSearch.addAll(result.getData()); + adapter.addData(dataSearch); + + } + }); + } + + +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/DetailActivity.java b/src/weapon/app/src/main/java/com/test/weapon/DetailActivity.java new file mode 100644 index 0000000..7fd0188 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/DetailActivity.java @@ -0,0 +1,209 @@ +package com.test.weapon; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import com.bumptech.glide.Glide; +import com.google.android.material.tabs.TabLayout; +import com.test.weapon.bean.GetWeaponList; +import com.test.weapon.fragment.TabDayFragment; +import com.test.weapon.fragment.TabMonthFragment; +import com.test.weapon.fragment.TabWeekFragment; +import com.test.weapon.util.AppData; +import com.test.weapon.util.ViewPagerForScrollView; + +import java.util.ArrayList; +import java.util.List; + +import cn.pedant.SweetAlert.SweetAlertDialog; +import es.dmoral.toasty.Toasty; + +public class DetailActivity extends AppCompatActivity { + private Context context; + private ImageView topImage; + private TextView textView; + private TabLayout tabLayout; + private ViewPagerForScrollView viewPager; + private TextView text_view_detail; + private List detailList; + private TextView text_view_detail_info; + private int detailNum; + private ImageView icon_go_pk; + GetWeaponList bean; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.detail_page); + bean= (GetWeaponList) getIntent().getSerializableExtra("bean"); + + //这个registerForActivityResult方法要写在Activity的onCreate方法里(在Activity创建的时候就要创建出来,不能等到使用的时候再创建,不然会报错LifecycleOwner com.xx.MainActivity@28b4e79 is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.)。 + ActivityResultLauncher intentActivityResultLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == RESULT_OK) { + //获取返回的结果 + + GetWeaponList beans = (GetWeaponList) result.getData().getSerializableExtra("data"); + if (beans.getName().equals(bean.getName())){ + Toasty.info(DetailActivity.this,"您选择的武器重复,请重新选择").show(); + }else { + StringBuffer stringBuffer=new StringBuffer(); + if (beans.getCartridgeCapacity()(); + detailList.add("手枪,外观很小巧,很容易随身隐蔽携带。由于手枪的射程比较近,威力也比较小,所以手枪在战场上起不了什么大作用。但是大部分国家的士兵在战场上都会带一把手枪作为辅助性的武器,当其它武器弹药用完了,就会使用手枪。还有一个就是在近距离的时候,也会使用手枪。"); + detailList.add("冲锋枪,一般的冲锋枪也是使用手枪子弹,威力和射程跟手枪差不多,但是冲锋枪的射击速度非常快。冲锋枪适合在巷战或是近距离枪战,主要用于近距离内火力压制。"); + detailList.add("机枪,主要分成两种,一种是轻机枪,另一种是重机枪。大部分的轻机枪发射步枪子弹,而重机枪是发射大口径的子弹。不管是轻机枪还是重机枪射程都很远,威力也很大,主要是用于远距离火力压制。"); + detailList.add("狙击枪,射程远,威力大,精准度高,但是需要一定的技术才能使用,一般都是狙击手才会使用狙击枪。在战场上,狙击枪主要是用来射杀敌方的主要人物,还有一些超大口径的狙击枪也可以打击地面上各种车辆,轻型坦克,装甲车等目标。"); + detailList.add("霰弹枪,这是一种很特殊的枪械,发射的子弹里面装有很多颗小弹丸,杀伤力范围很广,但是射程比较近。霰弹枪主要用于近距离枪战,不需要精确的瞄准就可以射击,是近距离内打击密集人群的最好枪械。"); + detailList.add("名称中未包含枪械类型,请添加详细名称"); + + switch (bean.getName()){ + case "手枪": + detailNum=0; + break; + case "冲锋枪": + detailNum=1; + break; + case "机枪": + detailNum=2; + break; + case "狙击枪": + detailNum=3; + break; + case "霰弹枪": + detailNum=4; + break; + default: + detailNum=5; + break; + + } + text_view_detail_info.setText(detailList.get(detailNum)); + icon_go_pk.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(context, ChooseActivity.class); + intentActivityResultLauncher.launch(intent); + } + }); + + + + } + + // ViewPager的适配器 + private class MyPagerAdapter extends FragmentPagerAdapter { + + public MyPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + switch (position) { + case 0: + TabDayFragment fragment=new TabDayFragment(); + Bundle bundle=new Bundle(); + bundle.putInt("index",getIntent().getIntExtra("index",-1)); + bundle.putSerializable("data", bean); + fragment.setArguments(bundle); + return fragment; + case 1: + TabWeekFragment fragment1=new TabWeekFragment(); + Bundle bundle1=new Bundle(); + bundle1.putInt("index",getIntent().getIntExtra("index",-1)); + bundle1.putSerializable("data", bean); + fragment1.setArguments(bundle1); + return fragment1; + case 2: + TabMonthFragment fragment2=new TabMonthFragment(); + Bundle bundle2=new Bundle(); + bundle2.putInt("index",getIntent().getIntExtra("index",-1)); + bundle2.putSerializable("data", bean); + fragment2.setArguments(bundle2); + return fragment2; + default: + return null; + } + } + + @Override + public int getCount() { + return 3; + } + + @Nullable + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return "日报"; + case 1: + return "周报"; + case 2: + return "月报"; + default: + return null; + } + } + } + + } diff --git a/src/weapon/app/src/main/java/com/test/weapon/LoginActivity.java b/src/weapon/app/src/main/java/com/test/weapon/LoginActivity.java new file mode 100644 index 0000000..f1b9476 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/LoginActivity.java @@ -0,0 +1,60 @@ +package com.test.weapon; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.gyf.immersionbar.ImmersionBar; + +import es.dmoral.toasty.Toasty; + +/** + * 登录 + */ +public class LoginActivity extends AppCompatActivity { + private EditText etUserName; + private EditText etPassword; + private Button btnLogin; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + ImmersionBar.with(this) + .statusBarDarkFont(true, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度 + .init(); + etUserName=(EditText) findViewById(R.id.et_userName); + etPassword=(EditText) findViewById(R.id.et_password); + btnLogin=(Button) findViewById(R.id.btn_login); + btnLogin.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + login(); + } + }); + } + + /** + * 登录方法 + */ + private void login(){ + String userName=etUserName.getText().toString().trim(); + String password=etPassword.getText().toString().trim(); + if (TextUtils.isEmpty(userName)){ + Toasty.info(LoginActivity.this, "请输入用户名", Toast.LENGTH_SHORT, true).show(); + return; + } + if (TextUtils.isEmpty(password)){ + Toasty.info(LoginActivity.this, "请输入密码", Toast.LENGTH_SHORT, true).show(); + return; + } + Toasty.success(LoginActivity.this, "登录成功!", Toast.LENGTH_SHORT, true).show(); + startActivity(new Intent(LoginActivity.this,MainActivity.class)); + finish(); + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/MainActivity.java b/src/weapon/app/src/main/java/com/test/weapon/MainActivity.java new file mode 100644 index 0000000..f5d6fb6 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/MainActivity.java @@ -0,0 +1,277 @@ +package com.test.weapon; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.util.TimeUtils; +import androidx.fragment.app.Fragment; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.gyf.immersionbar.ImmersionBar; +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.hjq.http.listener.OnHttpListener; +import com.hjq.toast.Toaster; +import com.luck.picture.lib.basic.PictureSelector; +import com.luck.picture.lib.config.SelectMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.interfaces.OnResultCallbackListener; +import com.test.weapon.api.ReturnWeaponListApi; +import com.test.weapon.fragment.FixInAdvanceFragment; +import com.test.weapon.fragment.HistoryFragment; +import com.test.weapon.fragment.LocationAlarmFragment; +import com.test.weapon.fragment.RemindFragment; +import com.test.weapon.http.HttpData; +import com.test.weapon.util.ShadeTabViewVertical; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import cn.pedant.SweetAlert.SweetAlertDialog; +import es.dmoral.toasty.Toasty; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener, OnHttpListener { + private ViewPager2 viewPager; + private ShadeTabViewVertical mainHome; + private ShadeTabViewVertical mainNeedDealt; + private ShadeTabViewVertical mainMineCenter; + private ShadeTabViewVertical mainMineHistory; + private ImageView img_search; + private TextView tvTitle; + private ImageView imgFaceAuth; + + private List mTabs = new ArrayList(); + private FragmentStateAdapter mAdapter; + private List mTabIndicator = new ArrayList<>(); + private int mPage; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + ImmersionBar.with(this) + .statusBarDarkFont(true, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度 + .init(); + viewPager=findViewById(R.id.viewPager); + mainHome=findViewById(R.id.main_home); + mainNeedDealt=findViewById(R.id.main_need_dealt); + img_search=findViewById(R.id.img_search); + mainMineCenter=findViewById(R.id.main_mine_center); + mainMineHistory=findViewById(R.id.main_history); + tvTitle=findViewById(R.id.tv_title); + imgFaceAuth=findViewById(R.id.img_faceAuth); + mainHome.setOnClickListener(this::onClick); + mainNeedDealt.setOnClickListener(this::onClick); + mainMineCenter.setOnClickListener(this::onClick); + mainMineHistory.setOnClickListener(this::onClick); + imgFaceAuth.setOnClickListener(this::onClick); + img_search.setOnClickListener(this::onClick); + initDatas(); + + } + + /** + * 初始化各个fragment + */ + private void initDatas() { + mTabs.add(new FixInAdvanceFragment()); + mTabs.add(new LocationAlarmFragment()); + mTabs.add(new HistoryFragment()); + + mTabs.add(new RemindFragment()); + mAdapter = new FragmentStateAdapter(getSupportFragmentManager(),getLifecycle()) { + @NonNull + @Override + public Fragment createFragment(int position) { + return mTabs.get(position); + } + + @Override + public int getItemCount() { + return mTabs.size(); + } + }; + initTabIndicator(); + + viewPager.setAdapter(mAdapter); + viewPager.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);//防止切换页面时刷新fragment + viewPager.setUserInputEnabled(false);//禁止滑动 + mPage = getIntent().getIntExtra("page", 0); + setViewPagerSelect(mPage); + getData(); + + } + + /** + * 设置滑动页面的选择 + * + * @param page + */ + public void setViewPagerSelect(int page) { + resetTabsStatus(); + mTabIndicator.get(page).setIconAlpha(0); + viewPager.setCurrentItem(page, false); + } + + //添加变色的底部Icon + private void initTabIndicator() { + mTabIndicator.add(mainHome); + mTabIndicator.add(mainNeedDealt); + mTabIndicator.add(mainMineHistory); + mTabIndicator.add(mainMineCenter); + + + mainHome.setIconAlpha(0); + } + + + /** + * 重置Tab状态 + */ + private void resetTabsStatus() { + for (int i = 0; i < mTabIndicator.size(); i++) { + mTabIndicator.get(i).setIconAlpha(1); + } + } + + @Override + public void onClick(View v) { + resetTabsStatus(); + switch (v.getId()) { + case R.id.main_home: + mTabIndicator.get(0).setIconAlpha(0); + viewPager.setCurrentItem(0, false); + tvTitle.setText("预定武器"); + break; + case R.id.main_need_dealt: + mTabIndicator.get(1).setIconAlpha(0); + viewPager.setCurrentItem(1, false); + tvTitle.setText("定位报警"); + break; + case R.id.main_mine_center: + mTabIndicator.get(3).setIconAlpha(0); + viewPager.setCurrentItem(3, false); + tvTitle.setText("历史记录"); + break; + case R.id.main_history: + mTabIndicator.get(2).setIconAlpha(0); + viewPager.setCurrentItem(2, false); + tvTitle.setText("提醒归还"); + break; + case R.id.img_faceAuth: + faceAuth(); + break; + case R.id.img_search: + startActivity(new Intent(this,SearchActivity.class)); + break; + } + } + + /** + * 模拟人脸认证 + */ + private void faceAuth(){ + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .isCameraAroundState(true)//是否开启前置摄像头;系统相机 只支持部分机型 + .forResult(new OnResultCallbackListener() { + @Override + public void onResult(ArrayList result) { + if (!TextUtils.isEmpty(result.get(0).getPath())){ + //实例化Random对象 + Random random = new Random(); + //首先在 [1,10] 区间(10个数)随机获取一个数 + int i = random.nextInt(10) % (10 - 1 + 1) + 1; + //然后根据中间概率来设置 if 条件语句的区间,达到效果 + if (i <= 7) {//人脸认证成功 + Toasty.success(MainActivity.this, "人脸认证成功!", Toast.LENGTH_SHORT, true).show(); + } else {//人脸认证失败 + Toasty.error(MainActivity.this, "人脸认证失败!", Toast.LENGTH_SHORT, true).show(); + } + }else{ + Toasty.info(MainActivity.this, "您已取消人脸认证!", Toast.LENGTH_SHORT, true).show(); + } + + } + + @Override + public void onCancel() { + Toasty.info(MainActivity.this, "您已取消人脸认证!", Toast.LENGTH_SHORT, true).show(); + } + }); + + } + void getData(){ + + Map map=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + + EasyHttp.post(this) + .api(new ReturnWeaponListApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(this) { + + @Override + public void onSucceed(HttpData> result) { + for (int i=0;i) result).getMessage()); + } + } + + @Override + public void onFail(Exception e) { + + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/SearchActivity.java b/src/weapon/app/src/main/java/com/test/weapon/SearchActivity.java new file mode 100644 index 0000000..7239de1 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/SearchActivity.java @@ -0,0 +1,208 @@ +package com.test.weapon; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; + +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.hjq.http.listener.OnHttpListener; +import com.test.weapon.Adapter.SearchProductAdapter; +import com.test.weapon.api.GetWeaponApi; +import com.test.weapon.bean.GetWeaponList; +import com.test.weapon.http.HttpData; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SearchActivity extends AppCompatActivity { + private Context context; + private ImageView ivEmpty; + private EditText etSearch; + private TextView tvSearch; + private RecyclerView rvSearch; + private String keyword;//关键字 + private List dataSearch; + private SearchProductAdapter adapter; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_search); + initView(); + context=this; + } + + private void initView(){ + findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + ivEmpty=findViewById(R.id.iv_empty); + etSearch=findViewById(R.id.et_search); + tvSearch=findViewById(R.id.tv_search); + rvSearch=findViewById(R.id.rv_search); + ivEmpty.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + etSearch.setText(""); + } + }); + addListener(); + adapter = new SearchProductAdapter(R.layout.item_search_products); + rvSearch.setLayoutManager(new LinearLayoutManager(SearchActivity.this)); + rvSearch.setAdapter(adapter); + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + GetWeaponList detail= (GetWeaponList) adapter.getData().get(position); + Intent intent = new Intent(SearchActivity.this, DetailActivity.class); + GetWeaponList bean= (GetWeaponList) adapter.getData().get(position); + intent.putExtra("bean",bean); + startActivity(intent); + } + }); + initData(); + } + private void initData(){ + dataSearch= new ArrayList<>(); + Map map=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + EasyHttp.post(this) + .api(new GetWeaponApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(new OnHttpListener() { + + + @Override + public void onSucceed(Object o) { + + } + + @Override + public void onFail(Exception e) { + + } + }) { + + @Override + public void onSucceed(HttpData> result) { + dataSearch.addAll(result.getData()); + } + }); + } + + /** + * 取出搜索商品信息 + */ + private void searchData(String keyword){ + + + + if (dataSearch.size()>0){ + List temp=new ArrayList<>(); + for (int i = 0; i < dataSearch.size(); i++) { + if (dataSearch.get(i).getName().contains(keyword)||dataSearch.get(i).getBulletCaliber().toString().contains(keyword)||dataSearch.get(i).getCartridgeCapacity().toString().contains(keyword)||dataSearch.get(i).getEffectiveRange().toString().contains(keyword)){ + temp.add(dataSearch.get(i)); + } + } + adapter.setNewData(temp); + } + + } + + private void addListener(){ + etSearch.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + //在EditText输入前,先调用一次该方法 + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + //在EditText输入过程中,不断的回调该方法 + String keyword = charSequence.toString(); + if (keyword.isEmpty()){ + adapter.setNewData(new ArrayList<>()); + }else{ + searchData(keyword); + } + } + + @Override + public void afterTextChanged(Editable editable) { + //在EditText输入完成后,调用一次该方法 + keyword = editable.toString().trim(); + if (keyword.isEmpty()){ + adapter.setNewData(new ArrayList<>()); + }else{ + searchData(keyword); + } + } + }); + + etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) {//按下搜索 + if (keyword!=null){ + keyword = v.getText().toString().trim(); + searchData(keyword); + hideKeyBoard(); + }else { + hideKeyBoard(); + } + } + return false; + //返回true,保留软键盘。false,隐藏软键盘 + } + }); + + tvSearch.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (keyword.isEmpty()){ + return; + } + searchData(keyword); + hideKeyBoard(); + } + }); + } + + private void hideKeyBoard() { + + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + + if (imm.isActive() && getCurrentFocus() != null) { + + if (getCurrentFocus().getWindowToken() != null) { + imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + } + } + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/api/GetWarningApi.java b/src/weapon/app/src/main/java/com/test/weapon/api/GetWarningApi.java new file mode 100644 index 0000000..3fb3f7f --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/api/GetWarningApi.java @@ -0,0 +1,26 @@ +package com.test.weapon.api; + + +import androidx.annotation.NonNull; + +import com.hjq.http.annotation.HttpHeader; +import com.hjq.http.annotation.HttpRename; +import com.hjq.http.config.IRequestApi; + +import java.util.List; + +public class GetWarningApi implements IRequestApi { + @NonNull + @Override + public String getApi() { + return "/weaponry/weaponry/getLocationWarningPageList"; + } + + + @HttpHeader + @HttpRename("Content-Type") + private String contentType = "application/json;charset=utf-8"; + + + + } diff --git a/src/weapon/app/src/main/java/com/test/weapon/api/GetWeaponApi.java b/src/weapon/app/src/main/java/com/test/weapon/api/GetWeaponApi.java new file mode 100644 index 0000000..b0f2210 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/api/GetWeaponApi.java @@ -0,0 +1,151 @@ +package com.test.weapon.api; + + +import androidx.annotation.NonNull; + +import com.hjq.http.annotation.HttpHeader; +import com.hjq.http.annotation.HttpRename; +import com.hjq.http.config.IRequestApi; + +import java.util.List; + +public class GetWeaponApi implements IRequestApi { + @NonNull + @Override + public String getApi() { + return "/weaponry/weaponry/getPageList"; + } + @HttpRename("pageNo") + private String pageNo; + + public GetWeaponApi setPageNo(String pageNo) { + this.pageNo = pageNo; + return this; + } + @HttpRename("pageSize") + private String pageSize; + + @HttpHeader + @HttpRename("Content-Type") + private String contentType = "application/json;charset=utf-8"; + + public GetWeaponApi setPageSize(String pageSize) { + this.pageSize = pageSize; + return this; + } + + public final static class Bean { + + private Integer code; + private String message; + private List data; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public static class DataDTO { + private String id; + private String name; + private String imgPath; + private String cartridgeCapacity; + private String bulletCaliber; + private String effectiveRange; + private String totalInventory; + private String lockInventory; + private String isLend; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getImgPath() { + return imgPath; + } + + public void setImgPath(String imgPath) { + this.imgPath = imgPath; + } + + public String getCartridgeCapacity() { + return cartridgeCapacity; + } + + public void setCartridgeCapacity(String cartridgeCapacity) { + this.cartridgeCapacity = cartridgeCapacity; + } + + public String getBulletCaliber() { + return bulletCaliber; + } + + public void setBulletCaliber(String bulletCaliber) { + this.bulletCaliber = bulletCaliber; + } + + public String getEffectiveRange() { + return effectiveRange; + } + + public void setEffectiveRange(String effectiveRange) { + this.effectiveRange = effectiveRange; + } + + public String getTotalInventory() { + return totalInventory; + } + + public void setTotalInventory(String totalInventory) { + this.totalInventory = totalInventory; + } + + public String getLockInventory() { + return lockInventory; + } + + public void setLockInventory(String lockInventory) { + this.lockInventory = lockInventory; + } + + public String getIsLend() { + return isLend; + } + + public void setIsLend(String isLend) { + this.isLend = isLend; + } + } + } + } diff --git a/src/weapon/app/src/main/java/com/test/weapon/api/LendWeaponApi.java b/src/weapon/app/src/main/java/com/test/weapon/api/LendWeaponApi.java new file mode 100644 index 0000000..267b7fe --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/api/LendWeaponApi.java @@ -0,0 +1,22 @@ +package com.test.weapon.api; + +import androidx.annotation.NonNull; + +import com.hjq.http.annotation.HttpHeader; +import com.hjq.http.annotation.HttpRename; +import com.hjq.http.config.IRequestApi; + +/** + * Created on 2023/3/24 + */ +public class LendWeaponApi implements IRequestApi { + @NonNull + @Override + public String getApi() { + return "/weaponry/weaponryLend/save"; + } + @HttpHeader + @HttpRename("Content-Type") + private String contentType = "application/json;charset=utf-8"; + +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/api/ReturnWeaponApi.java b/src/weapon/app/src/main/java/com/test/weapon/api/ReturnWeaponApi.java new file mode 100644 index 0000000..b0532d0 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/api/ReturnWeaponApi.java @@ -0,0 +1,30 @@ +package com.test.weapon.api; + +import androidx.annotation.NonNull; + +import com.hjq.http.annotation.HttpHeader; +import com.hjq.http.annotation.HttpRename; +import com.hjq.http.config.IRequestApi; + +/** + * Created on 2023/3/24 + */ +public class ReturnWeaponApi implements IRequestApi { + @NonNull + @Override + public String getApi() { + return "/weaponry/weaponryReturnRecord/save?"; + } + @HttpRename("lendRecordId") + private String lendRecordId; + + public ReturnWeaponApi setLendRecordId(String lendRecordId) { + this.lendRecordId = lendRecordId; + return this; + } + + @HttpHeader + @HttpRename("Content-Type") + private String contentType = "application/json;charset=utf-8"; + +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/api/ReturnWeaponListApi.java b/src/weapon/app/src/main/java/com/test/weapon/api/ReturnWeaponListApi.java new file mode 100644 index 0000000..91b9ce8 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/api/ReturnWeaponListApi.java @@ -0,0 +1,167 @@ +package com.test.weapon.api; + +import androidx.annotation.NonNull; + +import com.hjq.http.config.IRequestApi; + +/** + * Created on 2023/3/24 + */ +public class ReturnWeaponListApi implements IRequestApi { + @NonNull + @Override + public String getApi() { + return "/weaponry/weaponryLend/getPageList"; + } + public final static class Bean{ + + private String id; + private String weaponryId; + private String weaponryName; + private Integer num; + private Long returnTime; + private Integer returnStatus; + private WeaponryDTO weaponry; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getWeaponryId() { + return weaponryId; + } + + public void setWeaponryId(String weaponryId) { + this.weaponryId = weaponryId; + } + + public String getWeaponryName() { + return weaponryName; + } + + public void setWeaponryName(String weaponryName) { + this.weaponryName = weaponryName; + } + + public Integer getNum() { + return num; + } + + public void setNum(Integer num) { + this.num = num; + } + + public Long getReturnTime() { + return returnTime; + } + + public void setReturnTime(Long returnTime) { + this.returnTime = returnTime; + } + + public Integer getReturnStatus() { + return returnStatus; + } + + public void setReturnStatus(Integer returnStatus) { + this.returnStatus = returnStatus; + } + + public WeaponryDTO getWeaponry() { + return weaponry; + } + + public void setWeaponry(WeaponryDTO weaponry) { + this.weaponry = weaponry; + } + + public static class WeaponryDTO { + private String id; + private String name; + private String imgPath; + private String cartridgeCapacity; + private String bulletCaliber; + private String effectiveRange; + private String totalInventory; + private String lockInventory; + private String isLend; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getImgPath() { + return imgPath; + } + + public void setImgPath(String imgPath) { + this.imgPath = imgPath; + } + + public String getCartridgeCapacity() { + return cartridgeCapacity; + } + + public void setCartridgeCapacity(String cartridgeCapacity) { + this.cartridgeCapacity = cartridgeCapacity; + } + + public String getBulletCaliber() { + return bulletCaliber; + } + + public void setBulletCaliber(String bulletCaliber) { + this.bulletCaliber = bulletCaliber; + } + + public String getEffectiveRange() { + return effectiveRange; + } + + public void setEffectiveRange(String effectiveRange) { + this.effectiveRange = effectiveRange; + } + + public String getTotalInventory() { + return totalInventory; + } + + public void setTotalInventory(String totalInventory) { + this.totalInventory = totalInventory; + } + + public String getLockInventory() { + return lockInventory; + } + + public void setLockInventory(String lockInventory) { + this.lockInventory = lockInventory; + } + + public String getIsLend() { + return isLend; + } + + public void setIsLend(String isLend) { + this.isLend = isLend; + } + } + } + +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/bean/GetWeaponList.java b/src/weapon/app/src/main/java/com/test/weapon/bean/GetWeaponList.java new file mode 100644 index 0000000..50a50ec --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/bean/GetWeaponList.java @@ -0,0 +1,182 @@ +package com.test.weapon.bean; + +import java.io.Serializable; + +/** + * Created on 2023/3/23 + */ +public class GetWeaponList implements Serializable { + + private boolean isChoose=false; + private Object pageNo; + + public boolean isChoose() { + return isChoose; + } + + public void setChoose(boolean choose) { + isChoose = choose; + } + + private Object pageSize; + private String id; + private Long createTime; + private Long updateTime; + private Object updateTimeEnd; + private Object operator; + private Object remark; + private String name; + private String imgPath; + private Integer cartridgeCapacity; + private Double bulletCaliber; + private Integer effectiveRange; + private Integer totalInventory; + private Integer lockInventory; + private Integer status; + private Integer isLend; + private Object lockInventoryStart; + + public Object getPageNo() { + return pageNo; + } + + public void setPageNo(Object pageNo) { + this.pageNo = pageNo; + } + + public Object getPageSize() { + return pageSize; + } + + public void setPageSize(Object pageSize) { + this.pageSize = pageSize; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Long getCreateTime() { + return createTime; + } + + public void setCreateTime(Long createTime) { + this.createTime = createTime; + } + + public Long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + } + + public Object getUpdateTimeEnd() { + return updateTimeEnd; + } + + public void setUpdateTimeEnd(Object updateTimeEnd) { + this.updateTimeEnd = updateTimeEnd; + } + + public Object getOperator() { + return operator; + } + + public void setOperator(Object operator) { + this.operator = operator; + } + + public Object getRemark() { + return remark; + } + + public void setRemark(Object remark) { + this.remark = remark; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getImgPath() { + return imgPath; + } + + public void setImgPath(String imgPath) { + this.imgPath = imgPath; + } + + public Integer getCartridgeCapacity() { + return cartridgeCapacity; + } + + public void setCartridgeCapacity(Integer cartridgeCapacity) { + this.cartridgeCapacity = cartridgeCapacity; + } + + public Double getBulletCaliber() { + return bulletCaliber; + } + + public void setBulletCaliber(Double bulletCaliber) { + this.bulletCaliber = bulletCaliber; + } + + public Integer getEffectiveRange() { + return effectiveRange; + } + + public void setEffectiveRange(Integer effectiveRange) { + this.effectiveRange = effectiveRange; + } + + public Integer getTotalInventory() { + return totalInventory; + } + + public void setTotalInventory(Integer totalInventory) { + this.totalInventory = totalInventory; + } + + public Integer getLockInventory() { + return lockInventory; + } + + public void setLockInventory(Integer lockInventory) { + this.lockInventory = lockInventory; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getIsLend() { + return isLend; + } + + public void setIsLend(Integer isLend) { + this.isLend = isLend; + } + + public Object getLockInventoryStart() { + return lockInventoryStart; + } + + public void setLockInventoryStart(Object lockInventoryStart) { + this.lockInventoryStart = lockInventoryStart; + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/FixInAdvanceFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/FixInAdvanceFragment.java new file mode 100644 index 0000000..8514554 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/FixInAdvanceFragment.java @@ -0,0 +1,137 @@ +package com.test.weapon.fragment; + +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemChildClickListener; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.google.gson.Gson; +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.test.weapon.BaseFragment; +import com.test.weapon.Adapter.FixInAdvanceAdapter; +import com.test.weapon.DetailActivity; +import com.test.weapon.bean.GetWeaponList; +import com.test.weapon.api.LendWeaponApi; +import com.test.weapon.http.HttpData; +import com.test.weapon.R; +import com.test.weapon.api.GetWeaponApi; + +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import cn.pedant.SweetAlert.SweetAlertDialog; +import es.dmoral.toasty.Toasty; + +/** + * 预定武器 + */ +public class FixInAdvanceFragment extends BaseFragment { + private RecyclerView rvAdvance; + private long time; + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_fix_in_advance, container, true); + rvAdvance=view.findViewById(R.id.rv_advance); + initView(); + return view; + + } + + private void initView(){ + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND)+604800); + time= calendar.getTimeInMillis(); + + + FixInAdvanceAdapter adapter = new FixInAdvanceAdapter(R.layout.fix_in_advance_layout); + rvAdvance.setLayoutManager(new LinearLayoutManager(getContext())); + rvAdvance.setAdapter(adapter); + // 先注册需要点击的子控件id(注意,请不要写在convert方法里) + adapter.addChildClickViewIds(R.id.tv_lend); + adapter.setOnItemChildClickListener(new OnItemChildClickListener() { + @Override + public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + GetWeaponList bean= (GetWeaponList) adapter.getData().get(position); + switch (view.getId()){ + case R.id.tv_lend: + lendWeapon(bean.getId(),bean.getIsLend()); + if (bean.getIsLend()==0){ + bean.setIsLend(1); + adapter.notifyItemChanged(position); + } + + break; + } + } + }); + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + + Intent intent= new Intent(getContext(), DetailActivity.class); + GetWeaponList bean= (GetWeaponList) adapter.getData().get(position); + intent.putExtra("bean",bean); + intent.putExtra("index",position); + startActivity(intent); + } + }); + Mapmap=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + + + + EasyHttp.post(this) + .api(new GetWeaponApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(this) { + + @Override + public void onSucceed(HttpData> result) { + adapter.addData(result.getData()); + } + }); + + + } + void lendWeapon(String id,int type){ + + Mapmap=new HashMap<>(); + map.put("weaponryId",id); + map.put("num","1"); + map.put("returnTime",time+""); + + EasyHttp.post(this) + .api(new LendWeaponApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback(this) { + + @Override + public void onSucceed(HttpData result) { + + if (type==1){ + Toasty.success(getActivity(), "续借申请已提交,请等待审核!", Toast.LENGTH_SHORT, true).show(); + }else{ + Toasty.success(getActivity(), "借出申请已提交,请等待审核!", Toast.LENGTH_SHORT, true).show(); + } + } + }); + + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/HistoryFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/HistoryFragment.java new file mode 100644 index 0000000..d62492e --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/HistoryFragment.java @@ -0,0 +1,109 @@ +package com.test.weapon.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemChildClickListener; +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.test.weapon.Adapter.HistoryAdapter; +import com.test.weapon.Adapter.RemindAdapter; +import com.test.weapon.BaseFragment; +import com.test.weapon.R; +import com.test.weapon.api.ReturnWeaponApi; +import com.test.weapon.api.ReturnWeaponListApi; +import com.test.weapon.http.HttpData; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import es.dmoral.toasty.Toasty; + +/** + * 历史记录 + */ +public class HistoryFragment extends BaseFragment { + + private RecyclerView rvRemind; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_remind, container, false); + rvRemind=view.findViewById(R.id.rv_remind); + initView(); + return view; + } + private void initView(){ + HistoryAdapter adapter = new HistoryAdapter(R.layout.history_item_layout); + rvRemind.setLayoutManager(new LinearLayoutManager(getContext())); + rvRemind.setAdapter(adapter); + + // 先注册需要点击的子控件id(注意,请不要写在convert方法里) + adapter.addChildClickViewIds(R.id.tv_return); + adapter.setOnItemChildClickListener(new OnItemChildClickListener() { + @Override + public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + ReturnWeaponListApi.Bean bean= (ReturnWeaponListApi.Bean) adapter.getData().get(position); + + lendWeapon(bean.getId()); + bean.setReturnStatus(1); + adapter.notifyItemChanged(position); + } + }); + + Map map=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + + EasyHttp.post(this) + .api(new ReturnWeaponListApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(this) { + + @Override + public void onSucceed(HttpData> result) { + List list=new ArrayList<>(); + for (int i=0;i(this) { + @Override + public void onSucceed(HttpData result) { + Toasty.success(getActivity(), "归还成功!", Toast.LENGTH_SHORT, true).show(); + } + }); + } + +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/LocationAlarmFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/LocationAlarmFragment.java new file mode 100644 index 0000000..00cfebd --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/LocationAlarmFragment.java @@ -0,0 +1,72 @@ +package com.test.weapon.fragment; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.test.weapon.Adapter.LocationAlarmAdapter; +import com.test.weapon.BaseFragment; +import com.test.weapon.R; +import com.test.weapon.api.GetWarningApi; +import com.test.weapon.api.GetWeaponApi; +import com.test.weapon.bean.GetWeaponList; +import com.test.weapon.http.HttpData; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 定位报警 + */ +public class LocationAlarmFragment extends BaseFragment { + private RecyclerView rvLocation; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_location_alarm, container, false); + rvLocation = view.findViewById(R.id.rv_location); + initView(); + return view; + } + private void initView(){ + LocationAlarmAdapter adapter = new LocationAlarmAdapter(R.layout.location_alarm_layout); + rvLocation.setLayoutManager(new LinearLayoutManager(getContext())); + rvLocation.setAdapter(adapter); + + Map map=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + + EasyHttp.post(this) + .api(new GetWarningApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(this) { + + @Override + public void onSucceed(HttpData> result) { + adapter.addData(result.getData()); + } + }); + + + + + + + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/RemindFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/RemindFragment.java new file mode 100644 index 0000000..4109611 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/RemindFragment.java @@ -0,0 +1,115 @@ +package com.test.weapon.fragment; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemChildClickListener; +import com.hjq.http.EasyHttp; +import com.hjq.http.body.JsonBody; +import com.hjq.http.listener.HttpCallback; +import com.test.weapon.BaseFragment; +import com.test.weapon.api.ReturnWeaponApi; +import com.test.weapon.api.ReturnWeaponListApi; +import com.test.weapon.R; +import com.test.weapon.Adapter.RemindAdapter; +import com.test.weapon.http.HttpData; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import cn.pedant.SweetAlert.SweetAlertDialog; +import es.dmoral.toasty.Toasty; + +/** + * 提醒归还 + */ +public class RemindFragment extends BaseFragment { + + private RecyclerView rvRemind; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_remind, container, false); + rvRemind=view.findViewById(R.id.rv_remind); + initView(); + return view; + } + private void initView(){ + RemindAdapter adapter = new RemindAdapter(R.layout.remind_item_layout); + rvRemind.setLayoutManager(new LinearLayoutManager(getContext())); + rvRemind.setAdapter(adapter); + + // 先注册需要点击的子控件id(注意,请不要写在convert方法里) + adapter.addChildClickViewIds(R.id.tv_return); + adapter.setOnItemChildClickListener(new OnItemChildClickListener() { + @Override + public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + ReturnWeaponListApi.Bean bean= (ReturnWeaponListApi.Bean) adapter.getData().get(position); + + lendWeapon(bean.getId()); + bean.setReturnStatus(1); + adapter.notifyItemChanged(position); + } + }); + + Map map=new HashMap<>(); + map.put("pageNo","1"); + map.put("pageSize","10"); + + EasyHttp.post(this) + .api(new ReturnWeaponListApi() + ) + .body(new JsonBody(map)) + .request(new HttpCallback>>(this) { + + @Override + public void onSucceed(HttpData> result) { + List list=new ArrayList<>(); + for (int i=0;i(this) { + + @Override + public void onSucceed(HttpData result) { + Toasty.success(getActivity(), "归还成功!", Toast.LENGTH_SHORT, true).show(); + + } + }); + + } + +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/TabDayFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/TabDayFragment.java new file mode 100644 index 0000000..db48036 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/TabDayFragment.java @@ -0,0 +1,48 @@ +package com.test.weapon.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.test.weapon.BaseFragment; +import com.test.weapon.R; +import com.test.weapon.bean.GetWeaponList; + +import java.text.SimpleDateFormat; +import java.util.Date; + + +public class TabDayFragment extends BaseFragment { + TextView detail ; + GetWeaponList bean; + int position; + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_day, container, false); + detail=view.findViewById(R.id.detail_text); + Bundle bundle=getArguments(); + position=bundle.getInt("index"); + bean= (GetWeaponList) bundle.getSerializable("data"); + initView(); + + return view; + } + + private void initView() { + detail.setText( + "枪弹数量:"+bean.getBulletCaliber()+"\n" + + "入库数量:"+bean.getLockInventory()+"\n" + + "使用数量:"+position+3+"\n" + + "使用情况:正常\n" + + "使用时间:"+getDateToString(bean.getUpdateTime())+"\n" + + "使用目的:训练\n" + + "使用情况:正常"); + } + public static String getDateToString(long milSecond) { + Date date = new Date(milSecond); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.format(date); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/TabMonthFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/TabMonthFragment.java new file mode 100644 index 0000000..e25fb5c --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/TabMonthFragment.java @@ -0,0 +1,48 @@ +package com.test.weapon.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.test.weapon.BaseFragment; +import com.test.weapon.R; +import com.test.weapon.bean.GetWeaponList; + +import java.text.SimpleDateFormat; +import java.util.Date; + + +public class TabMonthFragment extends BaseFragment { + TextView detail ; + GetWeaponList bean; + int position; + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_day, container, false); + detail=view.findViewById(R.id.detail_text); + Bundle bundle=getArguments(); + position=bundle.getInt("index"); + bean= (GetWeaponList) bundle.getSerializable("data"); + initView(); + + return view; + } + + private void initView() { + detail.setText( + "枪弹数量:"+bean.getBulletCaliber()+"\n" + + "入库数量:"+bean.getLockInventory()+"\n" + + "使用数量:"+position+30+"\n" + + "使用情况:正常\n" + + "使用时间:"+getDateToString(bean.getUpdateTime())+"\n" + + "使用目的:训练\n" + + "使用情况:正常"); + } + public static String getDateToString(long milSecond) { + Date date = new Date(milSecond); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.format(date); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/fragment/TabWeekFragment.java b/src/weapon/app/src/main/java/com/test/weapon/fragment/TabWeekFragment.java new file mode 100644 index 0000000..ba32ab2 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/fragment/TabWeekFragment.java @@ -0,0 +1,48 @@ +package com.test.weapon.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.test.weapon.BaseFragment; +import com.test.weapon.R; +import com.test.weapon.bean.GetWeaponList; + +import java.text.SimpleDateFormat; +import java.util.Date; + + +public class TabWeekFragment extends BaseFragment { + TextView detail ; + GetWeaponList bean; + int position; + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_day, container, false); + detail=view.findViewById(R.id.detail_text); + Bundle bundle=getArguments(); + position=bundle.getInt("index"); + bean= (GetWeaponList) bundle.getSerializable("data"); + initView(); + + return view; + } + + private void initView() { + detail.setText( + "枪弹数量:"+bean.getBulletCaliber()+"\n" + + "入库数量:"+bean.getLockInventory()+"\n" + + "使用数量:"+position+7+"\n" + + "使用情况:正常\n" + + "使用时间:"+getDateToString(bean.getUpdateTime())+"\n" + + "使用目的:训练\n" + + "使用情况:正常"); + } + public static String getDateToString(long milSecond) { + Date date = new Date(milSecond); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.format(date); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/http/ErrorResponseCodeException.java b/src/weapon/app/src/main/java/com/test/weapon/http/ErrorResponseCodeException.java new file mode 100644 index 0000000..ee4e510 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/http/ErrorResponseCodeException.java @@ -0,0 +1,9 @@ +package com.test.weapon.http; + +public class ErrorResponseCodeException extends Exception{ + public ErrorResponseCodeException(String message){ + super(message);//写的异常调用父类的方法,传给父类 + } + +} + diff --git a/src/weapon/app/src/main/java/com/test/weapon/http/HttpData.java b/src/weapon/app/src/main/java/com/test/weapon/http/HttpData.java new file mode 100644 index 0000000..1871346 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/http/HttpData.java @@ -0,0 +1,51 @@ +package com.test.weapon.http; + +import okhttp3.Headers; + + +public class HttpData { + + /** 请求头 */ + private Headers headers; + + /** 返回码 */ + private int code; + /** 提示语 */ + private String message; + /** 数据 */ + private T data; + + public void setHeaders(Headers headers) { + this.headers = headers; + } + + public Headers getHeaders() { + return headers; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public T getData() { + return data; + } + + /** + * 是否请求成功 + */ + public boolean isRequestSuccess() { + return code == 200; + } + + /** + * 是否 Token 失效 + */ + public boolean isTokenFailure() { + return code == 1001; + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/http/ReleaseServer.java b/src/weapon/app/src/main/java/com/test/weapon/http/ReleaseServer.java new file mode 100644 index 0000000..93ce0d8 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/http/ReleaseServer.java @@ -0,0 +1,17 @@ +package com.test.weapon.http; + +import androidx.annotation.NonNull; + +import com.hjq.http.config.IRequestServer; +import com.test.weapon.util.AppData; + +/** + * Created on 2023/3/23 + */ +public class ReleaseServer implements IRequestServer { + @NonNull + @Override + public String getHost() { + return AppData.ApiAddress; + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/http/RequestHandler.java b/src/weapon/app/src/main/java/com/test/weapon/http/RequestHandler.java new file mode 100644 index 0000000..97641b2 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/http/RequestHandler.java @@ -0,0 +1,170 @@ +package com.test.weapon.http; + +import android.app.Application; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.hjq.gson.factory.GsonFactory; +import com.hjq.http.EasyLog; +import com.hjq.http.config.IRequestHandler; +import com.hjq.http.exception.CancelException; +import com.hjq.http.exception.DataException; +import com.hjq.http.exception.HttpException; +import com.hjq.http.exception.NetworkException; +import com.hjq.http.exception.NullBodyException; +import com.hjq.http.exception.ResponseException; +import com.hjq.http.exception.ServerException; +import com.hjq.http.exception.TimeoutException; +import com.hjq.http.request.HttpRequest; +import com.test.weapon.R; +; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Type; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; + +import okhttp3.Headers; +import okhttp3.Response; +import okhttp3.ResponseBody; + +/** + * Created on 2023/3/23 + */ +public class RequestHandler implements IRequestHandler { + private final Application mApplication; + + public RequestHandler(Application application) { + mApplication = application; + } + @NonNull + @Override + public Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull Type type) throws Exception { + if (Response.class.equals(type)) { + return response; + } + + if (!response.isSuccessful()) { + throw new ResponseException(String.format(mApplication.getString(R.string.http_response_error), + response.code(), response.message()), response); + } + + if (Headers.class.equals(type)) { + return response.headers(); + } + + ResponseBody body = response.body(); + if (body == null) { + throw new NullBodyException(mApplication.getString(R.string.http_response_null_body)); + } + + if (ResponseBody.class.equals(type)) { + return body; + } + + // 如果是用数组接收,判断一下是不是用 byte[] 类型进行接收的 + if(type instanceof GenericArrayType) { + Type genericComponentType = ((GenericArrayType) type).getGenericComponentType(); + if (byte.class.equals(genericComponentType)) { + return body.bytes(); + } + } + + if (InputStream.class.equals(type)) { + return body.byteStream(); + } + + if (Bitmap.class.equals(type)) { + return BitmapFactory.decodeStream(body.byteStream()); + } + + String text; + try { + text = body.string(); + } catch (IOException e) { + // 返回结果读取异常 + throw new DataException(mApplication.getString(R.string.http_data_explain_error), e); + } + + // 打印这个 Json 或者文本 + EasyLog.printJson(httpRequest, text); + + if (String.class.equals(type)) { + return text; + } + + final Object result; +// Gson sGson = new Gson(); + try { +// result= sGson.fromJson(text,type); + + result = GsonFactory.getSingletonGson().fromJson(text, type); + } catch (JsonSyntaxException e) { + // 返回结果读取异常 + throw new DataException(mApplication.getString(R.string.http_data_explain_error), e); + } + + if (result instanceof HttpData) { + HttpData model = (HttpData) result; + model.setHeaders(response.headers()); + + if (model.isRequestSuccess()) { + // 代表执行成功 + return result; + } + + if (model.isTokenFailure()) { + // 代表登录失效,需要重新登录 + throw new TokenException(mApplication.getString(R.string.http_token_error)); + } + + // 代表执行失败 + throw new ResultException(model.getMessage(), model); + } + return result; } + + @NonNull + @Override + public Exception requestFail(@NonNull HttpRequest httpRequest, @NonNull Exception e) { + if (e instanceof HttpException) { + if (e instanceof TokenException) { + // 登录信息失效,跳转到登录页 + + } + return e; + } + + if (e instanceof SocketTimeoutException) { + return new TimeoutException(mApplication.getString(R.string.http_server_out_time), e); + } + + if (e instanceof UnknownHostException) { + NetworkInfo info = ((ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); + // 判断网络是否连接 + if (info != null && info.isConnected()) { + // 有连接就是服务器的问题 + return new ServerException(mApplication.getString(R.string.http_server_error), e); + } + // 没有连接就是网络异常 + return new NetworkException(mApplication.getString(R.string.http_network_error), e); + } + + if (e instanceof IOException) { + // 出现该异常的两种情况 + // 1. 调用 EasyHttp.cancel + // 2. 网络请求被中断 + return new CancelException(mApplication.getString(R.string.http_request_cancel), e); + } + + return new HttpException(e.getMessage(), e); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/http/ResultException.java b/src/weapon/app/src/main/java/com/test/weapon/http/ResultException.java new file mode 100644 index 0000000..cd0f552 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/http/ResultException.java @@ -0,0 +1,29 @@ +package com.test.weapon.http; + +import androidx.annotation.NonNull; + +import com.hjq.http.exception.HttpException; +import com.test.weapon.http.HttpData; + +/** + * desc : 返回结果异常 + */ +public final class ResultException extends HttpException { + + private final HttpData mData; + + public ResultException(String message, HttpData data) { + super(message); + mData = data; + } + + public ResultException(String message, Throwable cause, HttpData data) { + super(message, cause); + mData = data; + } + + @NonNull + public HttpData getHttpData() { + return mData; + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/http/TokenException.java b/src/weapon/app/src/main/java/com/test/weapon/http/TokenException.java new file mode 100644 index 0000000..9275ce5 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/http/TokenException.java @@ -0,0 +1,17 @@ +package com.test.weapon.http; + +import com.hjq.http.exception.HttpException; + +/** + * desc : Token 失效异常 + */ +public final class TokenException extends HttpException { + + public TokenException(String message) { + super(message); + } + + public TokenException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/AppData.java b/src/weapon/app/src/main/java/com/test/weapon/util/AppData.java new file mode 100644 index 0000000..ffc9875 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/AppData.java @@ -0,0 +1,8 @@ +package com.test.weapon.util; + + +public class AppData { + public static String PicAddress="http://120.24.185.153:8088/file/"; + public static String ApiAddress="http://120.24.185.153:8088/"; + +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/HttpStreamOP.java b/src/weapon/app/src/main/java/com/test/weapon/util/HttpStreamOP.java new file mode 100644 index 0000000..3049ff5 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/HttpStreamOP.java @@ -0,0 +1,34 @@ +package com.test.weapon.util; + + +import com.test.weapon.http.ErrorResponseCodeException; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +public class HttpStreamOP implements ISource { + + @Override + public InputStream getInputStream(String urlPath) throws IOException, ErrorResponseCodeException { + + InputStream in = null; + URL url = new URL(urlPath); + HttpURLConnection connection =(HttpURLConnection) url.openConnection(); + + + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + + int code = connection.getResponseCode(); + if (code == 200){ + + in = connection.getInputStream(); + }else{ + throw new ErrorResponseCodeException("error code is"+code); + } + + return in; + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/ISource.java b/src/weapon/app/src/main/java/com/test/weapon/util/ISource.java new file mode 100644 index 0000000..bc7b9b3 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/ISource.java @@ -0,0 +1,11 @@ +package com.test.weapon.util; + + +import com.test.weapon.http.ErrorResponseCodeException; + +import java.io.IOException; +import java.io.InputStream; + +public interface ISource { + InputStream getInputStream(String path) throws IOException, ErrorResponseCodeException; +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/ImageCacheOP.java b/src/weapon/app/src/main/java/com/test/weapon/util/ImageCacheOP.java new file mode 100644 index 0000000..97acff5 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/ImageCacheOP.java @@ -0,0 +1,58 @@ +package com.test.weapon.util; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Base64; + + +import com.test.weapon.http.ErrorResponseCodeException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ImageCacheOP { + public Bitmap getBitmapFromUrl(Context context,String url){ + File file = new File(context.getCacheDir(), Base64.encodeToString(url.getBytes(),Base64.DEFAULT)); + if (file.exists() && file.length()>0){ + System.out.println("-------------------cache"); + }else { + try { + InputStream in = new HttpStreamOP().getInputStream(url); + writeImage2Cache(in,file); + } catch (IOException e) { + e.printStackTrace(); + } catch (ErrorResponseCodeException e) { + e.printStackTrace(); + } + System.out.println("-----------newload"); + } + return BitmapFactory.decodeFile(file.getAbsolutePath()); + + } + private void writeImage2Cache(InputStream in, File file) { + byte[] buffer = new byte[1024]; + int len = -1; + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + while ((len = in.read(buffer))!= -1){ + fos.write(buffer,0,len); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + }finally { + try { + in.close(); + fos.close(); + } catch (Exception e) {//不能只抓IO异常,还有空指针异常所以抓大异常 + e.printStackTrace(); + } + } + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/ShadeTabViewVertical.java b/src/weapon/app/src/main/java/com/test/weapon/util/ShadeTabViewVertical.java new file mode 100644 index 0000000..4ca836e --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/ShadeTabViewVertical.java @@ -0,0 +1,249 @@ +package com.test.weapon.util; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; +import android.os.Bundle; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import com.test.weapon.R; + +import cn.bingoogolapple.badgeview.BGABadgeViewHelper; +import cn.bingoogolapple.badgeview.BGABadgeable; +import cn.bingoogolapple.badgeview.BGADragDismissDelegate; + + +/** + * 描述: 渐变Tab + */ +public class ShadeTabViewVertical extends FrameLayout implements BGABadgeable { + + private BGABadgeViewHelper mBadgeViewHelper; + /** + * 一般状态下的图标 + */ + private ImageView iv_normalIcon; + + /** + * 选中状态下的图标 + */ + private ImageView iv_selectIcon; + + /** + * 一般状态下底部 TextView + */ + private TextView tv_normalLabel; + + /** + * 选中状态下底部 TextView + */ + private TextView tv_selectLabel; + + /** + * 选中状态下的文字颜色 + */ + private int selectTextColor; + + /** + * 底部文字默认大小(sp) + */ + private final int DEFAULT_TEXT_SIZE = 4; + + /** + * 一般状态下底部文字默认颜色 + */ + private final String DEFAULT_NORMAL_TEXT_COLOR = "#000000"; + + /** + * 选中状态下底部文字默认颜色 + */ + private final String DEFAULT_SELECT_TEXT_COLOR = "#000000"; + + private float alpha; + + public ShadeTabViewVertical(Context context, AttributeSet attrs) { + super(context, attrs); + mBadgeViewHelper = new BGABadgeViewHelper(this, context, attrs, BGABadgeViewHelper.BadgeGravity.RightCenter); + initView(context); + //获取自定义属性值 + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadeTabViewVertical, 0, 0); + BitmapDrawable normalIcon = (BitmapDrawable) typedArray.getDrawable(R.styleable.ShadeTabViewVertical_normalIcon); + BitmapDrawable selectIcon = (BitmapDrawable) typedArray.getDrawable(R.styleable.ShadeTabViewVertical_selectIcon); + String tab = typedArray.getString(R.styleable.ShadeTabViewVertical_tab); +// float textSize = typedArray.getDimension(R.styleable.ShadeTabView_textSize, +// TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, DEFAULT_TEXT_SIZE, getResources().getDisplayMetrics())); + int normalTextColor = typedArray.getColor(R.styleable.ShadeTabViewVertical_normalTextColor, Color.parseColor(DEFAULT_NORMAL_TEXT_COLOR)); + selectTextColor = typedArray.getColor(R.styleable.ShadeTabViewVertical_selectTextColor, Color.parseColor(DEFAULT_SELECT_TEXT_COLOR)); + //资源回收 + typedArray.recycle(); + //属性设置 + iv_normalIcon.setImageDrawable(normalIcon); + iv_selectIcon.setImageDrawable(selectIcon); + tv_normalLabel.setText(tab); + tv_normalLabel.setTextSize(12); + tv_normalLabel.setTextColor(normalTextColor); + tv_selectLabel.setText(tab); + tv_selectLabel.setTextSize(12); + tv_selectLabel.setTextColor(selectTextColor); + setIconAlpha(1); + } + + private void initView(Context context) { + LayoutInflater.from(context).inflate(R.layout.view_shade_tab_vertical, this); + iv_normalIcon = (ImageView) findViewById(R.id.iv_normal_icon); + iv_selectIcon = (ImageView) findViewById(R.id.iv_select_icon); + tv_normalLabel = (TextView) findViewById(R.id.tv_normal_label); + tv_selectLabel = (TextView) findViewById(R.id.tv_select_label); + } + /** + * 设置上下两层图片的透明度,alpha 值越小,图片的颜色越倾向于带有颜色的图层 + * @param alpha 透明度 + */ + public void setIconAlpha(float alpha) { + // setAlpha(float) 0.0f~1.0f 数值越大越不透明 + iv_selectIcon.setAlpha(1 - alpha); + iv_normalIcon.setAlpha(alpha); + tv_normalLabel.setAlpha(alpha); + tv_selectLabel.setAlpha(1 - alpha); + this.alpha = alpha; + } + + private static final String STATE_INSTANCE = "STATE_INSTANCE"; + + private static final String STATE_ALPHA = "STATE_ALPHA"; + + /** + * 保存状态 + * + * @return Parcelable + */ + @Override + protected Parcelable onSaveInstanceState() { + Bundle bundle = new Bundle(); + bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState()); + bundle.putFloat(STATE_ALPHA, alpha); + return bundle; + } + + /** + * 恢复状态 + * + * @param parcelable Parcelable + */ + @Override + protected void onRestoreInstanceState(Parcelable parcelable) { + Bundle bundle = (Bundle) parcelable; + super.onRestoreInstanceState(bundle.getParcelable(STATE_INSTANCE)); + setIconAlpha(bundle.getFloat(STATE_ALPHA)); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + return mBadgeViewHelper.onTouchEvent(event); + } + + @Override + public boolean callSuperOnTouchEvent(MotionEvent event) { + return super.onTouchEvent(event); + } + + @Override + public void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + mBadgeViewHelper.drawBadge(canvas); + } + + /** + * 显示圆点徽章 + */ + @Override + public void showCirclePointBadge() { + mBadgeViewHelper.showCirclePointBadge(); + } + + /** + * 显示文字徽章 + * + * @param badgeText + */ + @Override + public void showTextBadge(String badgeText) { + mBadgeViewHelper.showTextBadge(badgeText); + } + + /** + * 隐藏徽章 + */ + @Override + public void hiddenBadge() { + mBadgeViewHelper.hiddenBadge(); + } + + /** + * 显示图像徽章 + * + * @param bitmap + */ + @Override + public void showDrawableBadge(Bitmap bitmap) { + mBadgeViewHelper.showDrawable(bitmap); + } + + /** + * 设置拖动删除徽章的代理 + * + * @param delegate + */ + @Override + public void setDragDismissDelegate(BGADragDismissDelegate delegate) { + mBadgeViewHelper.setDragDismissDelegate(delegate); + } + + /** + * 是否显示徽章 + * + * @return + */ + @Override + public boolean isShowBadge() { + return mBadgeViewHelper.isShowBadge(); + } + + /** + * 是否可拖动 + * + * @return + */ + @Override + public boolean isDraggable() { + return mBadgeViewHelper.isDraggable(); + } + + /** + * 是否正在拖动 + * + * @return + */ + @Override + public boolean isDragging() { + return mBadgeViewHelper.isDragging(); + } + + /** + * 获取到徽章对象 + * @return + */ + @Override + public BGABadgeViewHelper getBadgeViewHelper() { + return mBadgeViewHelper; + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/SmartImageView.java b/src/weapon/app/src/main/java/com/test/weapon/util/SmartImageView.java new file mode 100644 index 0000000..6d0dc23 --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/SmartImageView.java @@ -0,0 +1,84 @@ +package com.test.weapon.util; + +import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; + +import androidx.annotation.Nullable; + +import com.test.weapon.R; + + +public class SmartImageView extends androidx.appcompat.widget.AppCompatImageView { + private Context context; + private Drawable mLoadingDrawable;//拿到图片的属性 + private Drawable mFailDrawable; + + public SmartImageView(Context context) {//普通的,只有控件的时候调用。只是new 了一个siv或者item里面没有长宽高这种属性的时候 + this(context,null); + } + + public SmartImageView(Context context, @Nullable AttributeSet attrs) {//item里面有各种各样属性的时候调用 + this(context, attrs,0); + } + + public SmartImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {//item里面配置了样式的时候 + super(context, attrs, defStyleAttr); + this.context=context; + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SmartImageView, defStyleAttr, 0); + //拿到MSV里所有的属性。 + mLoadingDrawable=typedArray.getDrawable(R.styleable.SmartImageView_onLoading); + mFailDrawable=typedArray.getDrawable(R.styleable.SmartImageView_onFail); + typedArray.recycle();//回收:样式池里有五组数据,调用这个方法就给你一个,用完一定要还回去,别人才能调用 + } + public void setImageUrl(String url,onCompleteListener onCompleteListener){ + if(url == null){ + if(this.mFailDrawable!=null){//放一张破图 + setImageDrawable(mFailDrawable); + return; + } + + } + if(this.mLoadingDrawable!=null){//放一张正在加载中的图片 + setImageDrawable(mLoadingDrawable); + + } + new Thread(){ + @Override + public void run() { + super.run(); + Bitmap bitmap = new ImageCacheOP().getBitmapFromUrl(SmartImageView.this.context, url); + ((Activity)(SmartImageView.this.context)).runOnUiThread(new Runnable() {//runOnUiThread在siv里没有Activity环境,要找Activity实例 + //只有context跟Activity有联系。在Adapter里findviewbyid里调用了siv三个方法中的某一个,把context传进去。 + //NewsAdapter是在MainActivity里调用,传进去的上下文也是MainActivity.所以siv里传进去的context实际上就是Activity. + @Override + public void run() { + if(bitmap!=null){ + setImageBitmap(bitmap); + if(onCompleteListener!=null) + onCompleteListener.onSuccess(bitmap); + }else{ + if(SmartImageView.this.mFailDrawable!=null){ + setImageDrawable(mFailDrawable); + } + if(onCompleteListener!=null) + onCompleteListener.onFail(); + } + } + }); + + } + }.start(); + + + } + + public interface onCompleteListener{//定义接口的原因:为了给外部使用siv的程序员,告诉他不仅能加载完图片还能告诉他加载成功还是失败。如果成功以后还在把图片在siv里传出去,可以做一些其他的业务逻辑。 + //回调:call back + void onSuccess(Bitmap bitmap); + void onFail(); + } +} diff --git a/src/weapon/app/src/main/java/com/test/weapon/util/ViewPagerForScrollView.java b/src/weapon/app/src/main/java/com/test/weapon/util/ViewPagerForScrollView.java new file mode 100644 index 0000000..49077bf --- /dev/null +++ b/src/weapon/app/src/main/java/com/test/weapon/util/ViewPagerForScrollView.java @@ -0,0 +1,65 @@ +package com.test.weapon.util; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +/** + * Created by xhl + * Created on 2023/6/21 + */ +public class ViewPagerForScrollView extends ViewPager { + private String Tag = "ViewPagerForScrollView"; + + public ViewPagerForScrollView(Context context) { + super(context); + } + + public ViewPagerForScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + addOnPageChangeListener(new OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + requestLayout(); + } + + @Override + public void onPageScrollStateChanged(int state) { + } + }); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int height = 0; + if (getAdapter() != null) { + int index = getCurrentItem(); + height = 0; + View v = ((Fragment) getAdapter().instantiateItem(this, index)).getView(); + if (v != null) { + v.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + height = v.getMeasuredHeight(); + } + } else { + height = 0; + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + int h = child.getMeasuredHeight(); + if (h > height) + height = h; + } + } + heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + +} \ No newline at end of file diff --git a/src/weapon/app/src/test/java/com/test/weapon/ExampleUnitTest.java b/src/weapon/app/src/test/java/com/test/weapon/ExampleUnitTest.java new file mode 100644 index 0000000..4a6c620 --- /dev/null +++ b/src/weapon/app/src/test/java/com/test/weapon/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.test.weapon; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/src/weapon/library/src/main/java/cn/pedant/SweetAlert/OptAnimationLoader.java b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/OptAnimationLoader.java new file mode 100644 index 0000000..371b35f --- /dev/null +++ b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/OptAnimationLoader.java @@ -0,0 +1,89 @@ +package cn.pedant.SweetAlert; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.util.AttributeSet; +import android.util.Xml; +import android.view.animation.*; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +public class OptAnimationLoader { + + public static Animation loadAnimation(Context context, int id) + throws Resources.NotFoundException { + + XmlResourceParser parser = null; + try { + parser = context.getResources().getAnimation(id); + return createAnimationFromXml(context, parser); + } catch (XmlPullParserException ex) { + Resources.NotFoundException rnf = new Resources.NotFoundException("Can't load animation resource ID #0x" + + Integer.toHexString(id)); + rnf.initCause(ex); + throw rnf; + } catch (IOException ex) { + Resources.NotFoundException rnf = new Resources.NotFoundException("Can't load animation resource ID #0x" + + Integer.toHexString(id)); + rnf.initCause(ex); + throw rnf; + } finally { + if (parser != null) parser.close(); + } + } + + private static Animation createAnimationFromXml(Context c, XmlPullParser parser) + throws XmlPullParserException, IOException { + + return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser)); + } + + private static Animation createAnimationFromXml(Context c, XmlPullParser parser, + AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException { + + Animation anim = null; + + // Make sure we are on a start tag. + int type; + int depth = parser.getDepth(); + + while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { + + if (type != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + + if (name.equals("set")) { + anim = new AnimationSet(c, attrs); + createAnimationFromXml(c, parser, (AnimationSet)anim, attrs); + } else if (name.equals("alpha")) { + anim = new AlphaAnimation(c, attrs); + } else if (name.equals("scale")) { + anim = new ScaleAnimation(c, attrs); + } else if (name.equals("rotate")) { + anim = new RotateAnimation(c, attrs); + } else if (name.equals("translate")) { + anim = new TranslateAnimation(c, attrs); + } else { + try { + anim = (Animation) Class.forName(name).getConstructor(Context.class, AttributeSet.class).newInstance(c, attrs); + } catch (Exception te) { + throw new RuntimeException("Unknown animation name: " + parser.getName() + " error:" + te.getMessage()); + } + } + + if (parent != null) { + parent.addAnimation(anim); + } + } + + return anim; + + } +} diff --git a/src/weapon/library/src/main/java/cn/pedant/SweetAlert/ProgressHelper.java b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/ProgressHelper.java new file mode 100644 index 0000000..98dc4b5 --- /dev/null +++ b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/ProgressHelper.java @@ -0,0 +1,167 @@ +package cn.pedant.SweetAlert; + +import android.content.Context; + +import com.pnikosis.materialishprogress.ProgressWheel; + +public class ProgressHelper { + private ProgressWheel mProgressWheel; + private boolean mToSpin; + private float mSpinSpeed; + private int mBarWidth; + private int mBarColor; + private int mRimWidth; + private int mRimColor; + private boolean mIsInstantProgress; + private float mProgressVal; + private int mCircleRadius; + + public ProgressHelper(Context ctx) { + mToSpin = true; + mSpinSpeed = 0.75f; + mBarWidth = ctx.getResources().getDimensionPixelSize(R.dimen.common_circle_width) + 1; + mBarColor = ctx.getResources().getColor(R.color.success_stroke_color); + mRimWidth = 0; + mRimColor = 0x00000000; + mIsInstantProgress = false; + mProgressVal = -1; + mCircleRadius = ctx.getResources().getDimensionPixelOffset(R.dimen.progress_circle_radius); + } + + public ProgressWheel getProgressWheel () { + return mProgressWheel; + } + + public void setProgressWheel (ProgressWheel progressWheel) { + mProgressWheel = progressWheel; + updatePropsIfNeed(); + } + + private void updatePropsIfNeed () { + if (mProgressWheel != null) { + if (!mToSpin && mProgressWheel.isSpinning()) { + mProgressWheel.stopSpinning(); + } else if (mToSpin && !mProgressWheel.isSpinning()) { + mProgressWheel.spin(); + } + if (mSpinSpeed != mProgressWheel.getSpinSpeed()) { + mProgressWheel.setSpinSpeed(mSpinSpeed); + } + if (mBarWidth != mProgressWheel.getBarWidth()) { + mProgressWheel.setBarWidth(mBarWidth); + } + if (mBarColor != mProgressWheel.getBarColor()) { + mProgressWheel.setBarColor(mBarColor); + } + if (mRimWidth != mProgressWheel.getRimWidth()) { + mProgressWheel.setRimWidth(mRimWidth); + } + if (mRimColor != mProgressWheel.getRimColor()) { + mProgressWheel.setRimColor(mRimColor); + } + if (mProgressVal != mProgressWheel.getProgress()) { + if (mIsInstantProgress) { + mProgressWheel.setInstantProgress(mProgressVal); + } else { + mProgressWheel.setProgress(mProgressVal); + } + } + if (mCircleRadius != mProgressWheel.getCircleRadius()) { + mProgressWheel.setCircleRadius(mCircleRadius); + } + } + } + + public void resetCount() { + if (mProgressWheel != null) { + mProgressWheel.resetCount(); + } + } + + public boolean isSpinning() { + return mToSpin; + } + + public void spin() { + mToSpin = true; + updatePropsIfNeed(); + } + + public void stopSpinning() { + mToSpin = false; + updatePropsIfNeed(); + } + + public float getProgress() { + return mProgressVal; + } + + public void setProgress(float progress) { + mIsInstantProgress = false; + mProgressVal = progress; + updatePropsIfNeed(); + } + + public void setInstantProgress(float progress) { + mProgressVal = progress; + mIsInstantProgress = true; + updatePropsIfNeed(); + } + + public int getCircleRadius() { + return mCircleRadius; + } + + /** + * @param circleRadius units using pixel + * **/ + public void setCircleRadius(int circleRadius) { + mCircleRadius = circleRadius; + updatePropsIfNeed(); + } + + public int getBarWidth() { + return mBarWidth; + } + + public void setBarWidth(int barWidth) { + mBarWidth = barWidth; + updatePropsIfNeed(); + } + + public int getBarColor() { + return mBarColor; + } + + public void setBarColor(int barColor) { + mBarColor = barColor; + updatePropsIfNeed(); + } + + public int getRimWidth() { + return mRimWidth; + } + + public void setRimWidth(int rimWidth) { + mRimWidth = rimWidth; + updatePropsIfNeed(); + } + + public int getRimColor() { + return mRimColor; + } + + public void setRimColor(int rimColor) { + mRimColor = rimColor; + updatePropsIfNeed(); + } + + public float getSpinSpeed() { + return mSpinSpeed; + } + + public void setSpinSpeed(float spinSpeed) { + mSpinSpeed = spinSpeed; + updatePropsIfNeed(); + } +} diff --git a/src/weapon/library/src/main/java/cn/pedant/SweetAlert/Rotate3dAnimation.java b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/Rotate3dAnimation.java new file mode 100644 index 0000000..d71473b --- /dev/null +++ b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/Rotate3dAnimation.java @@ -0,0 +1,159 @@ +package cn.pedant.SweetAlert; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Camera; +import android.graphics.Matrix; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.animation.Animation; +import android.view.animation.Transformation; + +public class Rotate3dAnimation extends Animation { + private int mPivotXType = ABSOLUTE; + private int mPivotYType = ABSOLUTE; + private float mPivotXValue = 0.0f; + private float mPivotYValue = 0.0f; + + private float mFromDegrees; + private float mToDegrees; + private float mPivotX; + private float mPivotY; + private Camera mCamera; + private int mRollType; + + public static final int ROLL_BY_X = 0; + public static final int ROLL_BY_Y = 1; + public static final int ROLL_BY_Z = 2; + + protected static class Description { + public int type; + public float value; + } + + Description parseValue(TypedValue value) { + Description d = new Description(); + if (value == null) { + d.type = ABSOLUTE; + d.value = 0; + } else { + if (value.type == TypedValue.TYPE_FRACTION) { + d.type = (value.data & TypedValue.COMPLEX_UNIT_MASK) == + TypedValue.COMPLEX_UNIT_FRACTION_PARENT ? + RELATIVE_TO_PARENT : RELATIVE_TO_SELF; + d.value = TypedValue.complexToFloat(value.data); + return d; + } else if (value.type == TypedValue.TYPE_FLOAT) { + d.type = ABSOLUTE; + d.value = value.getFloat(); + return d; + } else if (value.type >= TypedValue.TYPE_FIRST_INT && + value.type <= TypedValue.TYPE_LAST_INT) { + d.type = ABSOLUTE; + d.value = value.data; + return d; + } + } + + d.type = ABSOLUTE; + d.value = 0.0f; + + return d; + } + + public Rotate3dAnimation (Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Rotate3dAnimation); + + mFromDegrees = a.getFloat(R.styleable.Rotate3dAnimation_fromDeg, 0.0f); + mToDegrees = a.getFloat(R.styleable.Rotate3dAnimation_toDeg, 0.0f); + mRollType = a.getInt(R.styleable.Rotate3dAnimation_rollType, ROLL_BY_X); + Description d = parseValue(a.peekValue(R.styleable.Rotate3dAnimation_pivotX)); + mPivotXType = d.type; + mPivotXValue = d.value; + + d = parseValue(a.peekValue(R.styleable.Rotate3dAnimation_pivotY)); + mPivotYType = d.type; + mPivotYValue = d.value; + + a.recycle(); + + initializePivotPoint(); + } + + public Rotate3dAnimation (int rollType, float fromDegrees, float toDegrees) { + mRollType = rollType; + mFromDegrees = fromDegrees; + mToDegrees = toDegrees; + mPivotX = 0.0f; + mPivotY = 0.0f; + } + + public Rotate3dAnimation (int rollType, float fromDegrees, float toDegrees, float pivotX, float pivotY) { + mRollType = rollType; + mFromDegrees = fromDegrees; + mToDegrees = toDegrees; + + mPivotXType = ABSOLUTE; + mPivotYType = ABSOLUTE; + mPivotXValue = pivotX; + mPivotYValue = pivotY; + initializePivotPoint(); + } + + public Rotate3dAnimation (int rollType, float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) { + mRollType = rollType; + mFromDegrees = fromDegrees; + mToDegrees = toDegrees; + + mPivotXValue = pivotXValue; + mPivotXType = pivotXType; + mPivotYValue = pivotYValue; + mPivotYType = pivotYType; + initializePivotPoint(); + } + + private void initializePivotPoint() { + if (mPivotXType == ABSOLUTE) { + mPivotX = mPivotXValue; + } + if (mPivotYType == ABSOLUTE) { + mPivotY = mPivotYValue; + } + } + + @Override + public void initialize(int width, int height, int parentWidth, int parentHeight) { + super.initialize(width, height, parentWidth, parentHeight); + mCamera = new Camera(); + mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth); + mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight); + } + + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + final float fromDegrees = mFromDegrees; + float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); + + final Matrix matrix = t.getMatrix(); + + mCamera.save(); + switch (mRollType) { + case ROLL_BY_X: + mCamera.rotateX(degrees); + break; + case ROLL_BY_Y: + mCamera.rotateY(degrees); + break; + case ROLL_BY_Z: + mCamera.rotateZ(degrees); + break; + } + mCamera.getMatrix(matrix); + mCamera.restore(); + + matrix.preTranslate(-mPivotX, -mPivotY); + matrix.postTranslate(mPivotX, mPivotY); + } +} \ No newline at end of file diff --git a/src/weapon/library/src/main/java/cn/pedant/SweetAlert/SuccessTickView.java b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/SuccessTickView.java new file mode 100644 index 0000000..c0db746 --- /dev/null +++ b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/SuccessTickView.java @@ -0,0 +1,121 @@ +package cn.pedant.SweetAlert; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Transformation; + +public class SuccessTickView extends View { + private float mDensity = -1; + private Paint mPaint; + private final float CONST_RADIUS = dip2px(1.2f); + private final float CONST_RECT_WEIGHT = dip2px(3); + private final float CONST_LEFT_RECT_W = dip2px(15); + private final float CONST_RIGHT_RECT_W = dip2px(25); + private final float MIN_LEFT_RECT_W = dip2px(3.3f); + private final float MAX_RIGHT_RECT_W = CONST_RIGHT_RECT_W + dip2px(6.7f); + + private float mMaxLeftRectWidth; + private float mLeftRectWidth; + private float mRightRectWidth; + private boolean mLeftRectGrowMode; + + public SuccessTickView(Context context) { + super(context); + init(); + } + + public SuccessTickView(Context context, AttributeSet attrs){ + super(context,attrs); + init(); + } + + private void init () { + mPaint = new Paint(); + mPaint.setColor(getResources().getColor(R.color.success_stroke_color)); + mLeftRectWidth = CONST_LEFT_RECT_W; + mRightRectWidth = CONST_RIGHT_RECT_W; + mLeftRectGrowMode = false; + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + int totalW = getWidth(); + int totalH = getHeight(); + // rotate canvas first + canvas.rotate(45, totalW / 2, totalH / 2); + + totalW /= 1.2; + totalH /= 1.4; + mMaxLeftRectWidth = (totalW + CONST_LEFT_RECT_W) / 2 + CONST_RECT_WEIGHT - 1; + + RectF leftRect = new RectF(); + if (mLeftRectGrowMode) { + leftRect.left = 0; + leftRect.right = leftRect.left + mLeftRectWidth; + leftRect.top = (totalH + CONST_RIGHT_RECT_W) / 2; + leftRect.bottom = leftRect.top + CONST_RECT_WEIGHT; + } else { + leftRect.right = (totalW + CONST_LEFT_RECT_W) / 2 + CONST_RECT_WEIGHT - 1; + leftRect.left = leftRect.right - mLeftRectWidth; + leftRect.top = (totalH + CONST_RIGHT_RECT_W) / 2; + leftRect.bottom = leftRect.top + CONST_RECT_WEIGHT; + } + + canvas.drawRoundRect(leftRect, CONST_RADIUS, CONST_RADIUS, mPaint); + + RectF rightRect = new RectF(); + rightRect.bottom = (totalH + CONST_RIGHT_RECT_W) / 2 + CONST_RECT_WEIGHT - 1; + rightRect.left = (totalW + CONST_LEFT_RECT_W) / 2; + rightRect.right = rightRect.left + CONST_RECT_WEIGHT; + rightRect.top = rightRect.bottom - mRightRectWidth; + canvas.drawRoundRect(rightRect, CONST_RADIUS, CONST_RADIUS, mPaint); + } + + public float dip2px(float dpValue) { + if(mDensity == -1) { + mDensity = getResources().getDisplayMetrics().density; + } + return dpValue * mDensity + 0.5f; + } + + public void startTickAnim () { + // hide tick + mLeftRectWidth = 0; + mRightRectWidth = 0; + invalidate(); + Animation tickAnim = new Animation() { + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + super.applyTransformation(interpolatedTime, t); + if (0.54 < interpolatedTime && 0.7 >= interpolatedTime) { // grow left and right rect to right + mLeftRectGrowMode = true; + mLeftRectWidth = mMaxLeftRectWidth * ((interpolatedTime - 0.54f) / 0.16f); + if (0.65 < interpolatedTime) { + mRightRectWidth = MAX_RIGHT_RECT_W * ((interpolatedTime - 0.65f) / 0.19f); + } + invalidate(); + } else if (0.7 < interpolatedTime && 0.84 >= interpolatedTime) { // shorten left rect from right, still grow right rect + mLeftRectGrowMode = false; + mLeftRectWidth = mMaxLeftRectWidth * (1 - ((interpolatedTime - 0.7f) / 0.14f)); + mLeftRectWidth = mLeftRectWidth < MIN_LEFT_RECT_W ? MIN_LEFT_RECT_W : mLeftRectWidth; + mRightRectWidth = MAX_RIGHT_RECT_W * ((interpolatedTime - 0.65f) / 0.19f); + invalidate(); + } else if (0.84 < interpolatedTime && 1 >= interpolatedTime) { // restore left rect width, shorten right rect to const + mLeftRectGrowMode = false; + mLeftRectWidth = MIN_LEFT_RECT_W + (CONST_LEFT_RECT_W - MIN_LEFT_RECT_W) * ((interpolatedTime - 0.84f) / 0.16f); + mRightRectWidth = CONST_RIGHT_RECT_W + (MAX_RIGHT_RECT_W - CONST_RIGHT_RECT_W) * (1 - ((interpolatedTime - 0.84f) / 0.16f)); + invalidate(); + } + } + }; + tickAnim.setDuration(750); + tickAnim.setStartOffset(100); + startAnimation(tickAnim); + } +} \ No newline at end of file diff --git a/src/weapon/library/src/main/java/cn/pedant/SweetAlert/SweetAlertDialog.java b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/SweetAlertDialog.java new file mode 100644 index 0000000..77be52d --- /dev/null +++ b/src/weapon/library/src/main/java/cn/pedant/SweetAlert/SweetAlertDialog.java @@ -0,0 +1,382 @@ +package cn.pedant.SweetAlert; + + +import android.app.Dialog; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationSet; +import android.view.animation.Transformation; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import com.pnikosis.materialishprogress.ProgressWheel; + +import java.util.List; + +public class SweetAlertDialog extends Dialog implements View.OnClickListener { + private View mDialogView; + private AnimationSet mModalInAnim; + private AnimationSet mModalOutAnim; + private Animation mOverlayOutAnim; + private Animation mErrorInAnim; + private AnimationSet mErrorXInAnim; + private AnimationSet mSuccessLayoutAnimSet; + private Animation mSuccessBowAnim; + private TextView mTitleTextView; + private TextView mContentTextView; + private String mTitleText; + private String mContentText; + private boolean mShowCancel; + private boolean mShowContent; + private String mCancelText; + private String mConfirmText; + private int mAlertType; + private FrameLayout mErrorFrame; + private FrameLayout mSuccessFrame; + private FrameLayout mProgressFrame; + private SuccessTickView mSuccessTick; + private ImageView mErrorX; + private View mSuccessLeftMask; + private View mSuccessRightMask; + private Drawable mCustomImgDrawable; + private ImageView mCustomImage; + private Button mConfirmButton; + private Button mCancelButton; + private ProgressHelper mProgressHelper; + private FrameLayout mWarningFrame; + private OnSweetClickListener mCancelClickListener; + private OnSweetClickListener mConfirmClickListener; + private boolean mCloseFromCancel; + + public static final int NORMAL_TYPE = 0; + public static final int ERROR_TYPE = 1; + public static final int SUCCESS_TYPE = 2; + public static final int WARNING_TYPE = 3; + public static final int CUSTOM_IMAGE_TYPE = 4; + public static final int PROGRESS_TYPE = 5; + + public static interface OnSweetClickListener { + public void onClick (SweetAlertDialog sweetAlertDialog); + } + + public SweetAlertDialog(Context context) { + this(context, NORMAL_TYPE); + } + + public SweetAlertDialog(Context context, int alertType) { + super(context, R.style.alert_dialog); + setCancelable(true); + setCanceledOnTouchOutside(false); + mProgressHelper = new ProgressHelper(context); + mAlertType = alertType; + mErrorInAnim = OptAnimationLoader.loadAnimation(getContext(), R.anim.error_frame_in); + mErrorXInAnim = (AnimationSet)OptAnimationLoader.loadAnimation(getContext(), R.anim.error_x_in); + // 2.3.x system don't support alpha-animation on layer-list drawable + // remove it from animation set + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) { + List childAnims = mErrorXInAnim.getAnimations(); + int idx = 0; + for (;idx < childAnims.size();idx++) { + if (childAnims.get(idx) instanceof AlphaAnimation) { + break; + } + } + if (idx < childAnims.size()) { + childAnims.remove(idx); + } + } + mSuccessBowAnim = OptAnimationLoader.loadAnimation(getContext(), R.anim.success_bow_roate); + mSuccessLayoutAnimSet = (AnimationSet)OptAnimationLoader.loadAnimation(getContext(), R.anim.success_mask_layout); + mModalInAnim = (AnimationSet) OptAnimationLoader.loadAnimation(getContext(), R.anim.modal_in); + mModalOutAnim = (AnimationSet) OptAnimationLoader.loadAnimation(getContext(), R.anim.modal_out); + mModalOutAnim.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + + } + + @Override + public void onAnimationEnd(Animation animation) { + mDialogView.setVisibility(View.GONE); + mDialogView.post(new Runnable() { + @Override + public void run() { + if (mCloseFromCancel) { + SweetAlertDialog.super.cancel(); + } else { + SweetAlertDialog.super.dismiss(); + } + } + }); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + // dialog overlay fade out + mOverlayOutAnim = new Animation() { + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + WindowManager.LayoutParams wlp = getWindow().getAttributes(); + wlp.alpha = 1 - interpolatedTime; + getWindow().setAttributes(wlp); + } + }; + mOverlayOutAnim.setDuration(120); + } + + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.alert_dialog); + + mDialogView = getWindow().getDecorView().findViewById(android.R.id.content); + mTitleTextView = (TextView)findViewById(R.id.title_text); + mContentTextView = (TextView)findViewById(R.id.content_text); + mErrorFrame = (FrameLayout)findViewById(R.id.error_frame); + mErrorX = (ImageView)mErrorFrame.findViewById(R.id.error_x); + mSuccessFrame = (FrameLayout)findViewById(R.id.success_frame); + mProgressFrame = (FrameLayout)findViewById(R.id.progress_dialog); + mSuccessTick = (SuccessTickView)mSuccessFrame.findViewById(R.id.success_tick); + mSuccessLeftMask = mSuccessFrame.findViewById(R.id.mask_left); + mSuccessRightMask = mSuccessFrame.findViewById(R.id.mask_right); + mCustomImage = (ImageView)findViewById(R.id.custom_image); + mWarningFrame = (FrameLayout)findViewById(R.id.warning_frame); + mConfirmButton = (Button)findViewById(R.id.confirm_button); + mCancelButton = (Button)findViewById(R.id.cancel_button); + mProgressHelper.setProgressWheel((ProgressWheel)findViewById(R.id.progressWheel)); + mConfirmButton.setOnClickListener(this); + mCancelButton.setOnClickListener(this); + + setTitleText(mTitleText); + setContentText(mContentText); + setCancelText(mCancelText); + setConfirmText(mConfirmText); + changeAlertType(mAlertType, true); + + } + + private void restore () { + mCustomImage.setVisibility(View.GONE); + mErrorFrame.setVisibility(View.GONE); + mSuccessFrame.setVisibility(View.GONE); + mWarningFrame.setVisibility(View.GONE); + mProgressFrame.setVisibility(View.GONE); + mConfirmButton.setVisibility(View.VISIBLE); + + mConfirmButton.setBackgroundResource(R.drawable.blue_button_background); + mErrorFrame.clearAnimation(); + mErrorX.clearAnimation(); + mSuccessTick.clearAnimation(); + mSuccessLeftMask.clearAnimation(); + mSuccessRightMask.clearAnimation(); + } + + private void playAnimation () { + if (mAlertType == ERROR_TYPE) { + mErrorFrame.startAnimation(mErrorInAnim); + mErrorX.startAnimation(mErrorXInAnim); + } else if (mAlertType == SUCCESS_TYPE) { + mSuccessTick.startTickAnim(); + mSuccessRightMask.startAnimation(mSuccessBowAnim); + } + } + + private void changeAlertType(int alertType, boolean fromCreate) { + mAlertType = alertType; + // call after created views + if (mDialogView != null) { + if (!fromCreate) { + // restore all of views state before switching alert type + restore(); + } + switch (mAlertType) { + case ERROR_TYPE: + mErrorFrame.setVisibility(View.VISIBLE); + break; + case SUCCESS_TYPE: + mSuccessFrame.setVisibility(View.VISIBLE); + // initial rotate layout of success mask + mSuccessLeftMask.startAnimation(mSuccessLayoutAnimSet.getAnimations().get(0)); + mSuccessRightMask.startAnimation(mSuccessLayoutAnimSet.getAnimations().get(1)); + break; + case WARNING_TYPE: + mConfirmButton.setBackgroundResource(R.drawable.red_button_background); + mWarningFrame.setVisibility(View.VISIBLE); + break; + case CUSTOM_IMAGE_TYPE: + setCustomImage(mCustomImgDrawable); + break; + case PROGRESS_TYPE: + mProgressFrame.setVisibility(View.VISIBLE); + mConfirmButton.setVisibility(View.GONE); + break; + } + if (!fromCreate) { + playAnimation(); + } + } + } + + public int getAlerType () { + return mAlertType; + } + + public void changeAlertType(int alertType) { + changeAlertType(alertType, false); + } + + + public String getTitleText () { + return mTitleText; + } + + public SweetAlertDialog setTitleText (String text) { + mTitleText = text; + if (mTitleTextView != null && mTitleText != null) { + mTitleTextView.setText(mTitleText); + } + return this; + } + + public SweetAlertDialog setCustomImage (Drawable drawable) { + mCustomImgDrawable = drawable; + if (mCustomImage != null && mCustomImgDrawable != null) { + mCustomImage.setVisibility(View.VISIBLE); + mCustomImage.setImageDrawable(mCustomImgDrawable); + } + return this; + } + + public SweetAlertDialog setCustomImage (int resourceId) { + return setCustomImage(getContext().getResources().getDrawable(resourceId)); + } + + public String getContentText () { + return mContentText; + } + + public SweetAlertDialog setContentText (String text) { + mContentText = text; + if (mContentTextView != null && mContentText != null) { + showContentText(true); + mContentTextView.setText(mContentText); + } + return this; + } + + public boolean isShowCancelButton () { + return mShowCancel; + } + + public SweetAlertDialog showCancelButton (boolean isShow) { + mShowCancel = isShow; + if (mCancelButton != null) { + mCancelButton.setVisibility(mShowCancel ? View.VISIBLE : View.GONE); + } + return this; + } + + public boolean isShowContentText () { + return mShowContent; + } + + public SweetAlertDialog showContentText (boolean isShow) { + mShowContent = isShow; + if (mContentTextView != null) { + mContentTextView.setVisibility(mShowContent ? View.VISIBLE : View.GONE); + } + return this; + } + + public String getCancelText () { + return mCancelText; + } + + public SweetAlertDialog setCancelText (String text) { + mCancelText = text; + if (mCancelButton != null && mCancelText != null) { + showCancelButton(true); + mCancelButton.setText(mCancelText); + } + return this; + } + + public String getConfirmText () { + return mConfirmText; + } + + public SweetAlertDialog setConfirmText (String text) { + mConfirmText = text; + if (mConfirmButton != null && mConfirmText != null) { + mConfirmButton.setText(mConfirmText); + } + return this; + } + + public SweetAlertDialog setCancelClickListener (OnSweetClickListener listener) { + mCancelClickListener = listener; + return this; + } + + public SweetAlertDialog setConfirmClickListener (OnSweetClickListener listener) { + mConfirmClickListener = listener; + return this; + } + + protected void onStart() { + mDialogView.startAnimation(mModalInAnim); + playAnimation(); + } + + /** + * The real Dialog.cancel() will be invoked async-ly after the animation finishes. + */ + @Override + public void cancel() { + dismissWithAnimation(true); + } + + /** + * The real Dialog.dismiss() will be invoked async-ly after the animation finishes. + */ + public void dismissWithAnimation() { + dismissWithAnimation(false); + } + + private void dismissWithAnimation(boolean fromCancel) { + mCloseFromCancel = fromCancel; + mConfirmButton.startAnimation(mOverlayOutAnim); + mDialogView.startAnimation(mModalOutAnim); + } + + @Override + public void onClick(View v) { + if (v.getId() == R.id.cancel_button) { + if (mCancelClickListener != null) { + mCancelClickListener.onClick(SweetAlertDialog.this); + } else { + dismissWithAnimation(); + } + } else if (v.getId() == R.id.confirm_button) { + if (mConfirmClickListener != null) { + mConfirmClickListener.onClick(SweetAlertDialog.this); + } else { + dismissWithAnimation(); + } + } + } + + public ProgressHelper getProgressHelper () { + return mProgressHelper; + } +} \ No newline at end of file