WaybillDispatch.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. package com.baoshi.swms.fragment;
  2. import android.content.Context;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.text.InputType;
  6. import android.view.Display;
  7. import android.view.KeyEvent;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.view.WindowManager;
  12. import android.view.inputmethod.EditorInfo;
  13. import android.view.inputmethod.InputMethodManager;
  14. import android.widget.AbsListView;
  15. import android.widget.AdapterView;
  16. import android.widget.EditText;
  17. import android.widget.ImageView;
  18. import android.widget.TextView;
  19. import android.widget.Toast;
  20. import androidx.annotation.NonNull;
  21. import androidx.annotation.Nullable;
  22. import androidx.fragment.app.Fragment;
  23. import com.baoshi.swms.activity.changeView.ListViewFooterChange;
  24. import com.baoshi.swms.activity.item.WaybillDispatchItemActivity;
  25. import com.baoshi.swms.adapter.WaybillDispatchList;
  26. import com.baoshi.swms.bean.Waybill;
  27. import com.baoshi.swms.bean.dto.WaybillData;
  28. import com.baoshi.swms.inter.OnRefreshListener;
  29. import com.baoshi.swms.net.callback.WasHandlerCallback;
  30. import com.baoshi.swms.net.subscribe.WasSubscribe;
  31. import com.baoshi.swms.part.InputEditDialog;
  32. import com.baoshi.swms.part.RefreshHeader;
  33. import com.baoshi.swms.R;
  34. import com.baoshi.swms.util.DateUtil;
  35. import com.baoshi.swms.util.Hint;
  36. import com.bigkoo.pickerview.builder.TimePickerBuilder;
  37. import com.bigkoo.pickerview.listener.OnTimeSelectListener;
  38. import com.bigkoo.pickerview.view.TimePickerView;
  39. import java.util.ArrayList;
  40. import java.util.Calendar;
  41. import java.util.Date;
  42. import java.util.HashMap;
  43. import java.util.List;
  44. import java.util.Map;
  45. /**
  46. * 运单调配Fragment
  47. *
  48. * @author Zhendong Zhou
  49. * @date 2021/12/6 11:37
  50. */
  51. public class WaybillDispatch extends Fragment implements View.OnClickListener, TextView.OnEditorActionListener ,
  52. InputEditDialog.OnTextSendListener, AbsListView.OnScrollListener, OnRefreshListener ,
  53. AdapterView.OnItemClickListener, OnTimeSelectListener {
  54. private static final String ARG_KEY = "VIEW_ID";
  55. private int id; //当前碎片视图ID
  56. private final List<Waybill> waybills = new ArrayList<>(); //listview数据池
  57. private final Map<String,Double> mapping = new HashMap<>(); //专线费映射
  58. private View rootView; //当前视图
  59. //局部控件对象
  60. private TextView view;
  61. private TextView fee;
  62. //滚动元素节点
  63. private int topIndex;
  64. private int status;
  65. //软键盘文本框对象
  66. private InputEditDialog mInputEditDialog;
  67. private RefreshHeader listView; //ListView对象
  68. private WaybillDispatchList adapter;
  69. private ListViewFooterChange viewChange; //变更视图对象
  70. private boolean isNoneLoad = false;
  71. private final HashMap<String,String> params = new HashMap<String,String>(){{
  72. put("search","");
  73. put("deliver_at","");
  74. put("page","1");
  75. put("paginate","20");
  76. }};
  77. private int currentIndex;
  78. //构造方法传递目标fragment碎片视图
  79. public static WaybillDispatch newInstance(int param) {
  80. WaybillDispatch fragment = new WaybillDispatch();
  81. Bundle args = new Bundle();
  82. args.putInt(ARG_KEY, param);
  83. fragment.setArguments(args);
  84. return fragment;
  85. }
  86. /**
  87. * dispatch生命周期
  88. * */
  89. //初始化
  90. @Override
  91. public void onCreate(Bundle savedInstanceState) {
  92. super.onCreate(savedInstanceState);
  93. if (getArguments() != null){
  94. id = getArguments().getInt(ARG_KEY);
  95. }
  96. }
  97. //加载视图
  98. @Override
  99. public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
  100. Bundle savedInstanceState) {
  101. if (rootView==null)rootView = inflater.inflate(id, container, false);
  102. return rootView;
  103. }
  104. //初始化activity 到此视图方才加载完毕
  105. @Override
  106. public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  107. super.onActivityCreated(savedInstanceState);
  108. //渲染视图与加载局部变量
  109. rendingView();
  110. //视图渲染完毕才能加载视图更新对象
  111. viewChange = new ListViewFooterChange(getActivity(), listView);
  112. //加载数据
  113. loadListViewItem();
  114. //注册事件
  115. registerEvent();
  116. }
  117. //子ITEM返回时的携参
  118. @Override
  119. public void onActivityResult(int requestCode, int resultCode,@Nullable Intent data) {
  120. if (data==null || requestCode!=1)return;
  121. waybills.set(currentIndex-1,(Waybill) data.getSerializableExtra("waybill"));
  122. adapter.notifyDataSetChanged();
  123. Hint.toastShort(getContext(),"修改成功",Hint.COMMON);
  124. }
  125. /**
  126. * 初始化与全局行为
  127. * */
  128. //注册事件
  129. private void registerEvent() {
  130. ImageView imgView = getActivity().findViewById(R.id.date_picker_2);
  131. ImageView edit = getActivity().findViewById(R.id.edit_fee);
  132. ImageView back = getActivity().findViewById(R.id.waybill_back);
  133. EditText searchView = getActivity().findViewById(R.id.search_waybill);
  134. //回退
  135. back.setOnClickListener(this);
  136. //搜索
  137. searchView.setOnEditorActionListener(this);
  138. //时间控件监听
  139. view.setOnClickListener(this);
  140. imgView.setOnClickListener(this);
  141. //文本框控件监听
  142. edit.setOnClickListener(this);
  143. //滚动条监听
  144. listView.setOnScrollListener(this);
  145. //下拉刷新
  146. listView.setOnRefreshListener(this);
  147. //listview item点击
  148. listView.setOnItemClickListener(this);
  149. }
  150. //渲染视图
  151. private void rendingView() {
  152. mInputEditDialog = new InputEditDialog(getActivity(), R.style.InputDialog, "请输入按日专线费", InputType.TYPE_NUMBER_FLAG_SIGNED);
  153. listView = getActivity().findViewById(R.id.bill_list);
  154. adapter = new WaybillDispatchList(waybills,getActivity());
  155. view = getActivity().findViewById(R.id.date_picker_1);
  156. fee = getActivity().findViewById(R.id.fee);
  157. listView.setAdapter(adapter);
  158. }
  159. //初始化listview
  160. private void loadListViewItem() {
  161. if (isNoneLoad)return; //正确做法应该卸载监听器 暂时不知 所以用标记来跳过加载
  162. viewChange.addLoadFooter();
  163. isNoneLoad = true;
  164. requestData(false);
  165. }
  166. //加载数据
  167. private void requestData(boolean after)
  168. {
  169. String search = params.get("search");
  170. String deliverAt = params.get("deliver_at");
  171. int page = Integer.parseInt(params.get("page"));
  172. int paginate = Integer.parseInt(params.get("paginate"));
  173. WasSubscribe.getDispatchList(search, deliverAt, page, paginate, new WasHandlerCallback<WaybillData>() {
  174. @Override
  175. public void onSuccess(WaybillData result) {
  176. ArrayList<Waybill> currentData = result.getWaybills();
  177. if (currentData.size()>0)mapping.putAll(result.getMapping());//合并映射
  178. if (after)waybills.clear();
  179. waybills.addAll(currentData);
  180. if (waybills.size()==0){
  181. view.setText("暂无");
  182. fee.setText("");
  183. }else{
  184. String date = currentData.get(0).getDeliverAt().substring(0,10);
  185. view.setText(date);
  186. fee.setText(mapping.get(date)==null ? "" : String.valueOf(mapping.get(date)));
  187. }
  188. super.onSuccess(result); //这里觉得何时执行onFinally
  189. if (currentData.size()<Integer.parseInt(params.get("paginate"))){
  190. viewChange.addLoadStopFooter();
  191. isNoneLoad = true; //如果本次加载数据不足N条 则标记加载完毕
  192. }else if (waybills.size()==0){ //如果加载完毕了 数据总量仍为0 那么属于没有数据 显示空数据视图
  193. viewChange.addLoadNoneFooter();
  194. isNoneLoad = true;
  195. }else isNoneLoad = false;
  196. if (after){
  197. listView.setAdapter(adapter);
  198. listView.onRefreshComplete();
  199. }else adapter.notifyDataSetChanged();
  200. }
  201. @Override
  202. public void onFinally() {
  203. listView.removeFooterView(viewChange.mLoadLayout);
  204. isNoneLoad = false;
  205. }
  206. });
  207. }
  208. /**
  209. * 控件获取与变更
  210. * */
  211. //专线费文本框控件
  212. private void showInputMsgDialog() {
  213. WindowManager windowManager = getActivity().getWindowManager();
  214. Display display = windowManager.getDefaultDisplay();
  215. WindowManager.LayoutParams lp = mInputEditDialog.getWindow().getAttributes();
  216. lp.width = (int) (display.getWidth()); //设置宽度
  217. mInputEditDialog.getWindow().setAttributes(lp);
  218. mInputEditDialog.setCancelable(true);
  219. mInputEditDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
  220. mInputEditDialog.show();
  221. }
  222. //初始化calender 时间选择器控件
  223. private void initCalendar() {
  224. String[] dateTxt = view.getText().toString().split("-");
  225. if (dateTxt.length!=3){
  226. Toast.makeText(getActivity(), "数据异常,无法处理", Toast.LENGTH_SHORT).show();
  227. return;
  228. }
  229. TimePickerView pvTime = new TimePickerBuilder(getActivity(), this).build();
  230. Calendar startDate = Calendar.getInstance();
  231. startDate.set(Integer.parseInt(dateTxt[0]), Integer.parseInt(dateTxt[1])-1,
  232. Integer.parseInt(dateTxt[2]));
  233. pvTime.setDate(startDate);
  234. pvTime.setTitleText("选择发货时间");
  235. pvTime.show();
  236. }
  237. /**
  238. * 事件监听实例
  239. * */
  240. @Override
  241. public void onClick(View v) {
  242. if (v.getId()==R.id.waybill_back){
  243. getActivity().finish();
  244. }else if (v.getId()==R.id.date_picker_1 || v.getId()==R.id.date_picker_2){
  245. initCalendar();
  246. }else if (v.getId()==R.id.edit_fee){
  247. showInputMsgDialog();
  248. mInputEditDialog.setmOnTextSendListener(this);
  249. }
  250. }
  251. @Override
  252. public boolean onEditorAction(TextView v, int i, KeyEvent keyEvent) {
  253. if (i == EditorInfo.IME_ACTION_SEARCH){
  254. InputMethodManager manager = ((InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE));
  255. if (manager != null)
  256. manager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
  257. String txt = v.getText().toString();
  258. if (!txt.equals(params.get("search"))){
  259. isNoneLoad = false;
  260. params.put("search", txt);
  261. params.put("deliver_at", "");
  262. params.put("page", "1");
  263. waybills.clear();
  264. adapter = new WaybillDispatchList(waybills,getActivity());
  265. listView.setAdapter(adapter);
  266. loadListViewItem();
  267. }
  268. }
  269. return false;
  270. }
  271. @Override
  272. public void onTextSend(String msg) {
  273. Double feeInfo = checkDailyBillingFee(msg);
  274. if (feeInfo==null){
  275. return;
  276. }
  277. String date = checkDailyBillingDate();
  278. if (date==null){
  279. return;
  280. }
  281. WasSubscribe.dailyBilling(date, feeInfo, new WasHandlerCallback<Boolean>() {
  282. @Override
  283. public void onSuccess(Boolean result) {
  284. if (result){
  285. fee.setText(msg);
  286. mapping.put(date,feeInfo);
  287. Hint.toastShort(getContext(), "修改成功", Hint.COMMON);
  288. }else{
  289. Hint.toastShort(getContext(), "专线费修改异常", Hint.ERROR);
  290. }
  291. }
  292. });
  293. }
  294. @Override
  295. public void onScrollStateChanged(AbsListView view, int scrollState) {
  296. status = scrollState;
  297. }
  298. @Override
  299. public void onScroll(AbsListView v, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  300. topIndex = firstVisibleItem;
  301. switch (this.status){
  302. case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
  303. if (topIndex+visibleItemCount==totalItemCount){
  304. if (!isNoneLoad)params.put("page",String.valueOf(Integer.parseInt(params.get("page"))+1));
  305. loadListViewItem();
  306. }
  307. String date = waybills.get(topIndex).getDeliverAt().substring(0,10);
  308. if (!date.equals(view.getText())){
  309. view.setText(date);
  310. fee.setText(mapping.get(date)==null ? "" : String.valueOf(mapping.get(date)));
  311. }
  312. break;
  313. case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
  314. break;
  315. case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
  316. }
  317. }
  318. @Override
  319. public void refreshData() {
  320. if (topIndex==0){
  321. params.put("search","");
  322. params.put("deliver_at","");
  323. params.put("page","1");
  324. requestData(true);
  325. } else listView.onRefreshComplete();
  326. }
  327. @Override
  328. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  329. currentIndex = position;
  330. Intent intent = new Intent(getActivity(), WaybillDispatchItemActivity.class);
  331. Bundle bundle = new Bundle();
  332. bundle.putSerializable("waybill", waybills.get(position-1));
  333. intent.putExtras(bundle);
  334. intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
  335. startActivityForResult(intent,1);
  336. }
  337. @Override
  338. public void onTimeSelect(Date date, View v) {
  339. String deliverDate = DateUtil.getTime(date);
  340. if (!deliverDate.equals("") && !deliverDate.equals(params.get("deliver_at"))){
  341. view.setText(deliverDate);
  342. isNoneLoad = false;
  343. params.put("search", "");
  344. params.put("deliver_at", deliverDate);
  345. params.put("page", "1");
  346. waybills.clear();
  347. adapter = new WaybillDispatchList(waybills,getActivity());
  348. listView.setAdapter(adapter);
  349. loadListViewItem();
  350. }
  351. }
  352. /**
  353. * 参数校验与格式化
  354. * */
  355. private Double checkDailyBillingFee(String msg){
  356. double feeInfo;
  357. try {
  358. feeInfo = Double.parseDouble(msg);
  359. }catch (NumberFormatException e){
  360. Hint.toastShort(getContext(), "输入非法,非数字与科学计数法", Hint.COMMON);
  361. return null;
  362. }
  363. return feeInfo;
  364. }
  365. private String checkDailyBillingDate(){
  366. String date = view.getText().toString();
  367. if (date.split("-").length!=3){
  368. Toast.makeText(getActivity(), "请选择正确日期", Toast.LENGTH_SHORT).show();
  369. return null;
  370. }
  371. return date;
  372. }
  373. }