Приложение “Блокнот”. Весь код приложения.

MainActivity

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.SearchView;

import com.example.sqlitejava.adapter.ListItem;
import com.example.sqlitejava.adapter.MainAdapter;
import com.example.sqlitejava.db.AppExecuter;
import com.example.sqlitejava.db.MyDbManager;
import com.example.sqlitejava.db.OnDataReceived;

import java.util.List;

public class MainActivity extends AppCompatActivity implements OnDataReceived {
private MyDbManager myDbManager;
private EditText edTitle, edDisc;
private RecyclerView rcView;
private MainAdapter mainAdapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
MenuItem item= menu.findItem(R.id.id_search);
SearchView sv = (SearchView)item.getActionView();
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}

@Override
public boolean onQueryTextChange(final String newText) {

readFromDb(newText);

return false;
}
});
return super.onCreateOptionsMenu(menu);
}

private void init() {

myDbManager = new MyDbManager(this);
edTitle = findViewById(R.id.edTitle);
edDisc = findViewById(R.id.edDesc);
rcView = findViewById(R.id.rcView);
mainAdapter = new MainAdapter(this);
rcView.setLayoutManager(new LinearLayoutManager(this));
getItemTouchHelper().attachToRecyclerView(rcView);
rcView.setAdapter(mainAdapter);
}

@Override
protected void onResume() {
super.onResume();

myDbManager.openDb();
readFromDb("");

}

public void onClickAdd(View view) {

Intent i = new Intent(MainActivity.this, EditActivity.class);
startActivity(i);
}

@Override
protected void onDestroy() {
super.onDestroy();
myDbManager.closeDb();
}

private ItemTouchHelper getItemTouchHelper(){
return new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}

@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
mainAdapter.removeItem(viewHolder.getAdapterPosition(), myDbManager);
}
});
}

private void readFromDb(final String text){

AppExecuter.getInstance().getSubIO().execute(new Runnable() {
@Override
public void run() {
myDbManager.getFromDb(text, MainActivity.this);
}
});

}

@Override
public void onReceived(final List<ListItem> list) {

AppExecuter.getInstance().getMainIO().execute(new Runnable() {
@Override
public void run() {
mainAdapter.updateAdapter(list);
}
});
}
}

EditActivity

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.sqlitejava.adapter.ListItem;
import com.example.sqlitejava.db.AppExecuter;
import com.example.sqlitejava.db.MyConstants;
import com.example.sqlitejava.db.MyDbManager;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class EditActivity extends AppCompatActivity {

private final int PICK_IMAGE_CODE = 123;
private ImageView imNewImage;
private ConstraintLayout imageContainer;
private FloatingActionButton fbAddImage;
private ImageButton imEditImage, imDeleteImage;
private EditText edTitle, edDesc;
private MyDbManager myDbManager;
private String tempUri = "empty";
private boolean isEditState = true;
private ListItem item;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
init();
getMyIntents();
}
@Override
protected void onResume() {
super.onResume();

myDbManager.openDb();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if(resultCode == RESULT_OK && requestCode == PICK_IMAGE_CODE && data != null){

tempUri = data.getData().toString();
imNewImage.setImageURI(data.getData());
getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_READ_URI_PERMISSION);

}
}

private void init(){

edTitle = findViewById(R.id.edTitle);
edDesc = findViewById(R.id.edDesc);
imNewImage = findViewById(R.id.imNewImage);
fbAddImage = findViewById(R.id.fbAddImage);
imageContainer = findViewById(R.id.imageContainer);
imEditImage = findViewById(R.id.imEditImage);
imDeleteImage = findViewById(R.id.imDeleteImage);
myDbManager = new MyDbManager(this);
}

private void getMyIntents(){

Intent i = getIntent();
if(i != null){

item = (ListItem)i.getSerializableExtra(MyConstants.LIST_ITEM_INTENT);

isEditState = i.getBooleanExtra(MyConstants.EDIT_STATE, true);

if(!isEditState){

edTitle.setText(item.getTitle());
edDesc.setText(item.getDesc());
if(!item.getUri().equals("empty")){
tempUri = item.getUri();
imageContainer.setVisibility(View.VISIBLE);
imNewImage.setImageURI(Uri.parse(item.getUri()));
imDeleteImage.setVisibility(View.GONE);
imEditImage.setVisibility(View.GONE);

}

}


}

}

public void onClickSave(View view) {

final String title = edTitle.getText().toString();
final String desc = edDesc.getText().toString();

if (title.equals("") || desc.equals("")) {

Toast.makeText(this, R.string.text_empty, Toast.LENGTH_SHORT).show();

} else {

if(isEditState){

AppExecuter.getInstance().getSubIO().execute(new Runnable() {
@Override
public void run() {
myDbManager.insertToDb(title, desc, tempUri);
}
});
Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();

} else {

myDbManager.updateItem(title, desc, tempUri,item.getId());
Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();

}
myDbManager.closeDb();
finish();

}
}
public void onClickDeleteImage(View view){

imNewImage.setImageResource(R.drawable.ic_image_def);
tempUri = "empty";
imageContainer.setVisibility(View.GONE);
fbAddImage.setVisibility(View.VISIBLE);
}

public void onClickAddImage(View view){
imageContainer.setVisibility(View.VISIBLE);
view.setVisibility(View.GONE);
}

public void onClickChooseImage(View view){

Intent chooser = new Intent(Intent.ACTION_OPEN_DOCUMENT);
chooser.setType("image/*");
startActivityForResult(chooser, PICK_IMAGE_CODE);

}
}

ListItem

import java.io.Serializable;

public class ListItem implements Serializable {

private String title;
private String desc;
private String uri = "empty";
private int id = 0;

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDesc() {
return desc;
}

public void setDesc(String desc) {
this.desc = desc;
}

public String getUri() {
return uri;
}

public void setUri(String uri) {
this.uri = uri;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}
}

MainAdapter

import android.content.Context;
import android.content.Intent;
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 com.example.sqlitejava.EditActivity;
import com.example.sqlitejava.R;
import com.example.sqlitejava.db.MyConstants;
import com.example.sqlitejava.db.MyDbManager;
import java.util.ArrayList;
import java.util.List;

public class MainAdapter extends RecyclerView.Adapter<MainAdapter.MyViewHolder> {
private Context context;
private List<ListItem> mainArray;


public MainAdapter(Context context) {
this.context = context;
mainArray = new ArrayList<>();
}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_list_layout, parent, false);
return new MyViewHolder(view, context, mainArray);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.setData(mainArray.get(position).getTitle());
}

@Override
public int getItemCount() {
return mainArray.size();
}

static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView tvTitle;
private Context context;
private List<ListItem> mainArray;

public MyViewHolder(@NonNull View itemView, Context context, List<ListItem> mainArray) {
super(itemView);
this.context = context;
this.mainArray = mainArray;
tvTitle = itemView.findViewById(R.id.tvTitle);
itemView.setOnClickListener(this);

}
public void setData(String title){
tvTitle.setText(title);
}

@Override
public void onClick(View v) {

Intent i = new Intent(context, EditActivity.class);
i.putExtra(MyConstants.LIST_ITEM_INTENT, mainArray.get(getAdapterPosition()));
i.putExtra(MyConstants.EDIT_STATE, false);
context.startActivity(i);


}
}
public void updateAdapter(List<ListItem> newList){

mainArray.clear();
mainArray.addAll(newList);
notifyDataSetChanged();
}

public void removeItem(int pos, MyDbManager dbManager){
dbManager.delete(mainArray.get(pos).getId());
mainArray.remove(pos);
notifyItemRangeChanged(0, mainArray.size());
notifyItemRemoved(pos);


}

}

OnDataReceived

import com.example.sqlitejava.adapter.ListItem;
import java.util.List;

public interface OnDataReceived {
void onReceived(List<ListItem> list);
}

MyDbManager

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.sqlitejava.adapter.ListItem;
import java.util.ArrayList;
import java.util.List;

public class MyDbManager {
private Context context;
private MyDbHelper myDbHelper;
private SQLiteDatabase db;

public MyDbManager(Context context) {
this.context = context;
myDbHelper = new MyDbHelper(context);
}
public void openDb(){
db = myDbHelper.getWritableDatabase();
}

public void insertToDb(String title, String disc, String uri){

ContentValues cv = new ContentValues();
cv.put(MyConstants.TITLE, title);
cv.put(MyConstants.DISC, disc);
cv.put(MyConstants.URI, uri);
db.insert(MyConstants.TABLE_NAME, null, cv);

}
public void updateItem(String title, String disc, String uri,int id){
String selection = MyConstants._ID + "=" + id;
ContentValues cv = new ContentValues();
cv.put(MyConstants.TITLE, title);
cv.put(MyConstants.DISC, disc);
cv.put(MyConstants.URI, uri);
db.update(MyConstants.TABLE_NAME,cv,selection, null);
}
public void delete(int id){
String selection = MyConstants._ID + "=" + id;
db.delete(MyConstants.TABLE_NAME,selection, null);
}

public void getFromDb(String searchText, OnDataReceived onDataReceived) {
final List<ListItem> tempList = new ArrayList<>();
String selection = MyConstants.TITLE + " like ?";
final Cursor cursor = db.query(MyConstants.TABLE_NAME, null, selection,
new String[]{"%" + searchText + "%"}, null, null, null);


while (cursor.moveToNext()) {
ListItem item = new ListItem();
String title = cursor.getString(cursor.getColumnIndex(MyConstants.TITLE));
String desc = cursor.getString(cursor.getColumnIndex(MyConstants.DISC));
String uri = cursor.getString(cursor.getColumnIndex(MyConstants.URI));
int _id = cursor.getInt(cursor.getColumnIndex(MyConstants._ID));
item.setTitle(title);
item.setDesc(desc);
item.setUri(uri);
item.setId(_id);
tempList.add(item);

}
cursor.close();
onDataReceived.onReceived(tempList);
}
public void closeDb(){
myDbHelper.close();
}

}

MyDbHelper

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;

public class MyDbHelper extends SQLiteOpenHelper {

public MyDbHelper(@Nullable Context context) {
super(context, MyConstants.DB_NAME, null, MyConstants.DB_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {

db.execSQL(MyConstants.TABLE_STRUCTURE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

db.execSQL(MyConstants.DROP_TABLE);
onCreate(db);

}
}

MyConstants

public class MyConstants {
public static final String EDIT_STATE = "edit_state";
public static final String LIST_ITEM_INTENT = "list_item_intent";
public static final String TABLE_NAME = "my_table";
public static final String _ID = "_id";
public static final String TITLE = "title";
public static final String DISC = "disc";
public static final String URI = "uri";
public static final String DB_NAME = "my_db.db";
public static final int DB_VERSION = 2;
public static final String TABLE_STRUCTURE = "CREATE TABLE IF NOT EXISTS " +
TABLE_NAME + " (" + _ID + " INTEGER PRIMARY KEY," + TITLE + " TEXT," + DISC + " TEXT," +
URI + " TEXT)";

public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
}

AppExecuter

import android.os.Handler;
import android.os.Looper;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AppExecuter {
private static AppExecuter instance;
private final Executor mainIO;
private final Executor subIO;

public AppExecuter(Executor mainIO, Executor subIO) {
this.mainIO = mainIO;
this.subIO = subIO;
}

public static AppExecuter getInstance(){

if(instance == null) instance = new AppExecuter( new MainThreadHandler(), Executors.newSingleThreadExecutor());
return instance;
}

public static class MainThreadHandler implements Executor{
private Handler mainHandler = new Handler(Looper.getMainLooper());

@Override
public void execute(Runnable command) {
mainHandler.post(command);
}
}

public Executor getMainIO() {
return mainIO;
}

public Executor getSubIO() {
return subIO;
}
}

activity_main.xml

<?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"
android:background="@color/blue_dark"
tools:context=".MainActivity">


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rcView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:onClick="onClickAdd"
app:backgroundTint="@color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_add" />
</androidx.constraintlayout.widget.ConstraintLayout>

activity_edit.xml

<?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"
android:background="@color/blue_dark"
tools:context=".EditActivity">

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/imageContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="4dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="@+id/edTitle"
app:layout_constraintStart_toStartOf="@+id/edTitle"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">

<ImageView
android:id="@+id/imNewImage"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:drawable/editbox_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_add_image" />

<ImageButton
android:id="@+id/imEditImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:onClick="onClickChooseImage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_edit" />

<ImageButton
android:id="@+id/imDeleteImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:onClick="onClickDeleteImage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@android:drawable/ic_menu_delete" />
</androidx.constraintlayout.widget.ConstraintLayout>

<EditText
android:id="@+id/edTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:background="@android:drawable/editbox_background"
android:ems="10"
android:hint="Title"
android:inputType="textPersonName"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageContainer" />

<EditText
android:id="@+id/edDesc"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@android:drawable/editbox_background"
android:ems="10"
android:gravity="top"
android:hint="Discription"
android:inputType="textMultiLine|textPersonName"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/edTitle"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/edTitle"
app:layout_constraintTop_toBottomOf="@+id/edTitle" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:alpha="0.6"
android:clickable="true"
android:onClick="onClickSave"
android:tint="#FFFFFF"
app:backgroundTint="@color/blue_dark"
app:layout_constraintBottom_toBottomOf="@+id/edDesc"
app:layout_constraintEnd_toEndOf="@+id/edDesc"
app:srcCompat="@drawable/ic_action_name" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fbAddImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:alpha="0.6"
android:clickable="true"
android:onClick="onClickAddImage"
app:layout_constraintBottom_toTopOf="@+id/floatingActionButton"
app:layout_constraintEnd_toEndOf="@+id/floatingActionButton"
app:srcCompat="@drawable/ic_add_image" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintGuide_percent="0.33105335"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

item_list_layout.xml

<?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="wrap_content"
android:layout_margin="5dp"
android:background="@color/colorPrimary">

<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="TextView"
android:textColor="@android:color/white"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="SearchView"
android:id="@+id/id_search"
android:icon="@drawable/ic_search"
app:showAsAction="ifRoom"
app:actionViewClass="android.widget.SearchView"
/>
</menu>

styles.xml

<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowFullscreen">true</item>
</style>
<style name="AppTheme.EditThem" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowFullscreen">true</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

</resources>

strings.xml

<resources>
<string name="app_name">SQLIteJava</string>
<string name="text_empty">Заголовок или содержание не заполнено!!</string>
<string name="saved">Сохранено!</string>
</resources>

3 комментария для “Приложение “Блокнот”. Весь код приложения.”

  1. День добрый! А как сделать бекап БД только не на удаленный сервер, а локально на устройстве и как вариант на домашний сервер?

  2. Еще вопрос
    Почему мы засунули в поток вставку записи
    myDbManager.insertToDb(title, desc, tempUri);
    а обновление нет
    myDbManager.updateItem(title, desc, tempUri,item.getId());

Добавить комментарий

Ваш адрес email не будет опубликован.