【Android】家庭记账本手机版开发报告三
一、说在前面
昨天 | 对第一天的框架结构进行了四方面的完善 |
今天 | 对界面显示和逻辑结构进行完善 |
问题 | 无 |
二、界面展示完善
1、使用可回收的列表recyclerView展示账单的信息,并设置数据项为卡片
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".AccountRecordFragment" android:id="@+id/frameLayout"> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/floatingActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:layout_margin="16dp" android:clickable="true" android:focusable="true" android:src="@drawable/ic_add_witer_24dp" tools:layout_conversion_absoluteHeight="56dp" tools:layout_conversion_absoluteWidth="56dp" tools:layout_editor_absoluteX="178dp" tools:layout_editor_absoluteY="659dp" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" tools:layout_conversion_absoluteHeight="731dp" tools:layout_conversion_absoluteWidth="411dp" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp" /> </FrameLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="?selectableItemBackground" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="4dp"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.1" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.95" /> <TextView android:id="@+id/textViewid" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/textviewid" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:text="1" /> <TextView android:id="@+id/textViewtype" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" android:text="@string/textviewtype" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/textViewtime" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textViewtime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/textviewtime" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="@+id/textViewtype" app:layout_constraintEnd_toStartOf="@+id/textViewmoney" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/textViewtype" app:layout_constraintTop_toTopOf="@+id/textViewtype" /> <TextView android:id="@+id/textViewmoney" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/textviewmoney" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="@+id/textViewtime" app:layout_constraintEnd_toStartOf="@+id/guideline5" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/textViewtime" app:layout_constraintTop_toTopOf="@+id/textViewtime" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> </LinearLayout>
卡片展示数据,点击有阴影效果
2、构建展示数据界面和添加数据页面和Navigation
1)构建展示数据界面
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".AccountRecordFragment" android:id="@+id/frameLayout"> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/floatingActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:layout_margin="16dp" android:clickable="true" android:focusable="true" android:src="@drawable/ic_add_witer_24dp" tools:layout_conversion_absoluteHeight="56dp" tools:layout_conversion_absoluteWidth="56dp" tools:layout_editor_absoluteX="178dp" tools:layout_editor_absoluteY="659dp" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" tools:layout_conversion_absoluteHeight="731dp" tools:layout_conversion_absoluteWidth="411dp" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp" /> </FrameLayout>
2)、构建动态添加数据界面
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/addLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".addFragment" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/account_record_title" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.1" /> <EditText android:id="@+id/editTexttype" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:autofillHints="" android:ems="10" android:hint="@string/cost_type" android:inputType="textPersonName" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" /> <EditText android:id="@+id/editTextmoney" android:layout_width="0dp" android:layout_height="wrap_content" android:autofillHints="" android:ems="10" android:hint="@string/cost_money" android:inputType="textPersonName" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/editTexttype" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="@+id/editTexttype" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.35" /> <Button android:id="@+id/buttonsubmit" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/button_submit" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/editTextmoney" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="@+id/editTextmoney" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.5" /> </androidx.constraintlayout.widget.ConstraintLayout>
3)、创建Navigation
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav" app:startDestination="@id/accountRecordFragment"> <fragment android:id="@+id/accountRecordFragment" android:name="com.me.familybookkeepingbook.AccountRecordFragment" android:label="account_record" tools:layout="@layout/fragment_account_record"> <action android:id="@+id/action_accountRecordFragment_to_addFragment" app:destination="@id/addFragment" /> </fragment> <fragment android:id="@+id/addFragment" android:name="com.me.familybookkeepingbook.addFragment" android:label="add" tools:layout="@layout/fragment_add" /> </navigation>
三、代码逻辑相应完善
1、适配器
package com.me.familybookkeepingbook; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; public class MyAdpter extends RecyclerView.Adapter <MyAdpter.MyViewHolder>{ List<AccountRecord> allAccountRecords = new ArrayList<>(); public void setAllAccountRecords(List<AccountRecord> allAccountRecords) { this.allAccountRecords = allAccountRecords; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); View itemView = layoutInflater.inflate(R.layout.cost_itme_c_1,parent,false); MyViewHolder holder = new MyViewHolder(itemView); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); return holder; } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { AccountRecord accountRecord = allAccountRecords.get(position); holder.textViewId.setText(String.valueOf(position+1)); holder.textViewMoney.setText(String.valueOf(accountRecord.getCostMoney())); holder.textViewTime.setText(accountRecord.getCostTime()); holder.textViewType.setText(accountRecord.getCostType()); } @Override public int getItemCount() { return allAccountRecords.size() ; } static class MyViewHolder extends RecyclerView.ViewHolder{ TextView textViewId,textViewType,textViewMoney,textViewTime; public MyViewHolder(@NonNull View itemView) { super(itemView); textViewId = itemView.findViewById(R.id.textViewid); textViewType = itemView.findViewById(R.id.textViewtype); textViewTime = itemView.findViewById(R.id.textViewtime); textViewMoney = itemView.findViewById(R.id.textViewmoney); } } }
2、数据展示
@Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); accountRecordViewModel = ViewModelProviders.of(requireActivity()).get(AccountRecordViewModel.class); recyclerView = requireActivity().findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity())); myAdpter = new MyAdpter(); recyclerView.setAdapter(myAdpter); accountRecordViewModel.getAllAcountRecord().observe(requireActivity(), new Observer<List<AccountRecord>>() { @Override public void onChanged(List<AccountRecord> accountRecords) { myAdpter.setAllAccountRecords(accountRecords); myAdpter.notifyDataSetChanged(); } }); floatingActionButton = requireActivity().findViewById(R.id.floatingActionButton); floatingActionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { NavController navController = Navigation.findNavController(v); navController.navigate(R.id.action_accountRecordFragment_to_addFragment); } }); }
3、进入添加界面自动聚焦到第一个输入框并弹出键盘添加完成后返回数据展示界面并去除键盘
1)、聚焦到第一个输入框并弹出键盘
editTextType.requestFocus(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editTextType,0);
2)、返回数据展示界面去除键盘
InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(),0);
4、获取添加界面数据并添加到数据库
package com.me.familybookkeepingbook; import android.content.Context; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.ViewModelProviders; import androidx.navigation.NavController; import androidx.navigation.Navigation; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import java.text.SimpleDateFormat; import java.util.Date; /** * A simple {@link Fragment} subclass. */ public class addFragment extends Fragment { private Button buttonSubmit; private EditText editTextType,editTextMoney; private AccountRecordViewModel accountRecordViewModel; public addFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_add, container, false); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); FragmentActivity activity = requireActivity(); accountRecordViewModel = ViewModelProviders.of(activity).get(AccountRecordViewModel.class); buttonSubmit = activity.findViewById(R.id.buttonsubmit); editTextMoney = activity.findViewById(R.id.editTextmoney); editTextType = activity.findViewById(R.id.editTexttype); buttonSubmit.setEnabled(false); editTextType.requestFocus(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editTextType,0); TextWatcher textWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { String type = editTextType.getText().toString().trim(); String money = editTextMoney.getText().toString().trim(); buttonSubmit.setEnabled(!type.isEmpty()&&!money.isEmpty()); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { } }; editTextType.addTextChangedListener(textWatcher); editTextMoney.addTextChangedListener(textWatcher); buttonSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String type = editTextType.getText().toString().trim(); String money = editTextMoney.getText().toString().trim(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd HH:mm");// HH:mm:ss //获取当前时间 Date date = new Date(System.currentTimeMillis()); Double money_d = Double.valueOf(money); AccountRecord accountRecord = new AccountRecord(1, simpleDateFormat.format(date),type,money_d); accountRecordViewModel.insertAccountRecord(accountRecord); NavController navController = Navigation.findNavController(v); navController.navigateUp(); InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(),0); } }); } }