Android studio course design development implementation --- Diary APP

Android studio course design development implementation - Diary APP



foreword

Hello, I am oy, introducing a simple diary APP.

1. Effect

1. Start page, guide page and login registration
insert image description here
2. Diary related functions
insert image description here
3. Personal center interface
insert image description here

2. Function introduction

1. Main functions

  1. Implement the application startup page and guide page
  2. Realize setting a password to enter the APP, and encrypt the password
  3. Realize the bottom navigation bar, divided into diary list, new diary, personal center module
  4. Realize the basic functions of deleting, modifying and adding to the diary
  5. Realize a round avatar, set the avatar through the photo album and take pictures and crop the picture. Can be saved in real time.
  6. Realize network update personal center beauty map.
  7. Display and close the password, jump to the application setting interface
  8. Dynamically obtain photo and album access permissions
    ...
    ...

2. Knowledge points involved

  1. Activity and fragment data transfer, page update, and mutual jump.
  2. SharedPrefrenced storage, file storage, file encryption.
  3. Android application permission acquisition and setting
  4. Use of controls: Button, EditText, AlertDialog, Imageview, ImageButton, viewPager2, Toolbar, RecycleView, NavigationButton, etc.
  5. Use of layout: LinearLayout, ConstraintLayout, RelativeLayout, etc.
  6. Call the Android system application
  7. Custom View: Bottom pop-up window (complex), circular avatar
  8. Glide framework use: network loading pictures
  9. Android Framework: MVC
     …

3. Implementation ideas

  1. MainActivity is implemented using BottomNavigationView, ViewPager2, and Toolbar.
public class MainActivity extends AppCompatActivity {
    
    
    private BottomNavigationView bottomNavigationView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initToolbar();
        initFragment();
        initNavigationBottom();
    }

    @SuppressLint("ResourceAsColor")
    private void initNavigationBottom() {
    
    
        bottomNavigationView = findViewById(R.id.navigation_bottom);
        bottomNavigationView.setItemIconTintList(null);
        bottomNavigationView.setOnNavigationItemSelectedListener(itemSelectedListener);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
    
        return super.onCreateOptionsMenu(menu);
    }

    private void initFragment() {
    
    
        DiariesFragment diariesFragment = getDiariesFragment();
        if (diariesFragment == null) {
    
    
            diariesFragment = new DiariesFragment();
            ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), diariesFragment, R.id.content);
        }
    }

    private DiariesFragment getDiariesFragment() {
    
    
        return (DiariesFragment) getSupportFragmentManager().findFragmentById(R.id.content);
    }

    private void initToolbar() {
    
    
        //设置顶部状态栏为透明
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

    private final BottomNavigationView.OnNavigationItemSelectedListener itemSelectedListener = item -> {
    
    
        switch (item.getItemId()) {
    
    
            case R.id.menu_diary:
                MeController.setToolbarVisibility(this);
                ActivityUtils.removeFragmentTOActivity(getSupportFragmentManager(), getSupportFragmentManager().findFragmentById(R.id.content));
                ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), new DiariesFragment(), R.id.content);
                break;
            case R.id.menu_me:
                findViewById(R.id.toolbar).setVisibility(View.GONE);
                ActivityUtils.removeFragmentTOActivity(getSupportFragmentManager(), getSupportFragmentManager().findFragmentById(R.id.content));
                ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), new MeFragment(), R.id.content);
                break;
            case R.id.menu_new:
                bottomNavigationView.setVisibility(View.GONE);
                MeController.setToolbarVisibility(this);
                ActivityUtils.removeFragmentTOActivity(getSupportFragmentManager(), getSupportFragmentManager().findFragmentById(R.id.content));
                ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), new AddDiaryFragment(), R.id.content);
                break;
        }
        return true;
    };
}

MainActivity的layout

<?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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:fitsSystemWindows="true"
            android:theme="@style/Widget.AppCompat.Toolbar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    </com.google.android.material.appbar.AppBarLayout>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/navigation_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:menu="@menu/menu_navigation"
        android:background="?android:attr/windowBackground"/>

</LinearLayout>
  1. Switch between different fragments in ViewPager2, and add diary, personal center and diary list to the corresponding navigation bar.
public class DiariesFragment extends Fragment {
    
    
    private DiariesController mController;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        mController = new DiariesController(this);
    }
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
    
        View root = inflater.inflate(R.layout.fragment_diaries, container, false);
        mController.setDiariesList(root.findViewById(R.id.diaries_list));
        return root;
    }

    @Override
    public void onResume() {
    
    
        super.onResume();
        mController.loadDiaries();
    }
}

DiariesFragment的layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/diaries_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>
public class AddDiaryFragment extends Fragment implements View.OnClickListener {
    
    
    private AddDiaryController mController;
    private View edit_layout;
    private Button btn_confirm;
    private EditText edit_title;
    private EditText edit_desc;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        mController = new AddDiaryController(this);
    }

    private void initView(View view) {
    
    
        btn_confirm = view.findViewById(R.id.add_diary_confirm);
        btn_confirm.setOnClickListener(this);
        edit_title = view.findViewById(R.id.edit_add_title);
        edit_desc = view.findViewById(R.id.edit_add_desc);
        edit_layout = view.findViewById(R.id.edit_layout);
        edit_layout.setOnClickListener(this);
    }



    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    
    
        inflater.inflate(R.menu.menu_cancel, menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
    
        switch (item.getItemId()) {
    
    
            case R.id.menu_cancel:
                mController.closeWriteDiary(getActivity().getSupportFragmentManager(), this);
                mController.setNavigationVisibility();
                return true;
        }
        return false;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
    
        View root = inflater.inflate(R.layout.fragment_add_diary, container, false);
        initView(root);
        return root;
    }

    @Override
    public void onDestroy() {
    
    
        super.onDestroy();
    }

    @Override
    public void onClick(View view) {
    
    
        switch (view.getId()) {
    
    
            case R.id.add_diary_confirm:
                mController.addDiaryToRepository(edit_title.getText().toString().trim(), edit_desc.getText().toString().trim());
                mController.setNavigationVisibility();
                mController.closeWriteDiary(getActivity().getSupportFragmentManager(), this);
                break;
            case R.id.edit_layout:
                mController.changeFocus(edit_desc);
                break;
        }
    }
}

AddDiaryFragment的layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:orientation="vertical">
        <EditText
            android:id="@+id/edit_add_title"
            android:hint="@string/add_title_hint"
            android:minLines="1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/edit_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_marginTop="5dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="10dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingStart="5dp"
            android:paddingTop="5dp"
            android:paddingEnd="5dp"
            android:paddingBottom="5dp"
            android:background="@drawable/edit_background">
            <EditText
                android:id="@+id/edit_add_desc"
                android:hint="@string/add_title_description"
                android:gravity="top"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scrollbars="vertical"
                android:background="@null"/>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">
        <Button
            android:id="@+id/add_diary_confirm"
            android:text="@string/btn_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>
  1. Save the application password encrypted and in the file. Get the password every time you log in and compare it.
public class LoginDirectActivity extends AppCompatActivity implements View.OnClickListener {
    
    
    private EditText edit_input_text;
    private Button btn_comeIn;
    private TextView tv_setPsw;
    private static final String TAG = "Login2Activity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_direct_login);
        bindView();
    }

    private void bindView() {
    
    
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        edit_input_text = findViewById(R.id.edit_login2_input_text);
        btn_comeIn = findViewById(R.id.btn_login2_comeIn);
        btn_comeIn.setOnClickListener(this);
        tv_setPsw = findViewById(R.id.tv_setPsw);
        tv_setPsw.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
    
    
        switch (v.getId()) {
    
    
            case R.id.tv_setPsw:
                Intent setPsw_intent = new Intent(LoginDirectActivity.this, LoginActivity.class);
                startActivity(setPsw_intent);
                LoginDirectActivity.this.finish();
//                overridePendingTransition(R.anim.out_to_left,R.anim.in_from_right);
                break;
            case R.id.btn_login2_comeIn:
                String psw = edit_input_text.getText().toString().trim();
                if (psw.isEmpty()) {
    
    
                    Toast.makeText(this, "密码不能为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                String readInfoByContext = FileUtils.readInfoByContext(this);
                if (psw.equals(readInfoByContext)) {
    
    
                    Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(this, MainActivity.class);
                    startActivity(intent);
//                    overridePendingTransition(R.anim.out_to_left,R.anim.in_from_right);
                } else {
    
    
                    Toast.makeText(this, "密码不正确!", Toast.LENGTH_SHORT).show();
                }
                break;

        }
    }
}

LoginDirectActivity 的layout

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".view.LoginDirectActivity">

    <Button
        android:id="@+id/btn_login2_comeIn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginEnd="40dp"
        android:text="进入"
        app:layout_constraintBottom_toTopOf="@+id/guideline5"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginEnd="40dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline7">

        <ImageView
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:src="@mipmap/come_in_key" />

        <EditText
            android:id="@+id/edit_login2_input_text"
            android:hint="输入您的密码"
            android:inputType="textPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>


    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.22" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.58" />

    <TextView
        android:id="@+id/tv_login2_password_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="输入密码"
        android:textSize="30sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline4" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.4" />

    <TextView
        android:id="@+id/tv_setPsw"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="设置密码"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="@+id/linearLayout"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout" />


</androidx.constraintlayout.widget.ConstraintLayout>
  1. Use SharedPrefrenced to store diary content and title.
public final class SharedPreferencesUtils {
    
    
    private static final SimpleArrayMap<String, SharedPreferencesUtils> mCaches = new SimpleArrayMap<>();
    private SharedPreferences mSharedPreferences;
    private SharedPreferencesUtils(final String spName, final int mode) {
    
    
        mSharedPreferences = YyApplication.get().getSharedPreferences(spName, mode);
    }

    public static SharedPreferencesUtils getInstance(String spName) {
    
    
        SharedPreferencesUtils utils = mCaches.get(spName);
        if (utils == null) {
    
    
            utils = new SharedPreferencesUtils(spName, Context.MODE_PRIVATE);
        }
        return utils;
    }

    public void put(final String key, final String value) {
    
    
        mSharedPreferences.edit().putString(key, value).apply();
    }

    public String get(final String key) {
    
    
        return mSharedPreferences.getString(key, "");
    }

    public void remove(final String key) {
    
    
        mSharedPreferences.edit().remove(key).apply();
    }
}

Summarize

The above is the content of today’s talk. This article only briefly introduces the Android Diary APP. It is necessary to master the above knowledge points and be able to better understand the application logic.

Guess you like

Origin blog.csdn.net/m0_49534667/article/details/128087389