Skip to content

Commit c5494f8

Browse files
committed
ListView has been replaced by a RecyclerView. Added an image to the Book class
1 parent a46339a commit c5494f8

File tree

13 files changed

+381
-92
lines changed

13 files changed

+381
-92
lines changed

Room database/app/build.gradle

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ apply plugin: 'com.android.application'
22

33
android {
44
namespace 'com.codeandcoke.mybooks'
5-
compileSdk 32
5+
compileSdk 34
66

77
defaultConfig {
88
applicationId "com.codeandcoke.mybooks"
9-
minSdk 21
9+
minSdk 32
1010
targetSdk 32
1111
versionCode 1
1212
versionName "1.0"
@@ -24,15 +24,21 @@ android {
2424
sourceCompatibility JavaVersion.VERSION_1_8
2525
targetCompatibility JavaVersion.VERSION_1_8
2626
}
27+
buildFeatures {
28+
viewBinding true
29+
}
2730

2831
}
2932

3033
dependencies {
3134
implementation fileTree(dir: 'libs', include: ['*.jar'])
3235

33-
implementation "androidx.room:room-runtime:2.4.3"
34-
annotationProcessor "androidx.room:room-compiler:2.4.3"
36+
implementation "androidx.room:room-runtime:2.6.1"
37+
annotationProcessor "androidx.room:room-compiler:2.6.1"
38+
39+
implementation 'androidx.recyclerview:recyclerview:1.3.2'
40+
implementation 'com.google.android.material:material:1.10.0'
3541

36-
implementation 'androidx.appcompat:appcompat:1.5.1'
42+
implementation 'androidx.appcompat:appcompat:1.6.1'
3743
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
3844
}

Room database/app/src/main/AndroidManifest.xml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@
88
android:roundIcon="@mipmap/ic_launcher_round"
99
android:supportsRtl="true"
1010
android:theme="@style/AppTheme">
11-
<activity android:name=".AddBook" android:exported="true"></activity>
12-
<activity android:name=".MainActivity" android:exported="true">
11+
<activity
12+
android:name=".BookDetailActivity"
13+
android:exported="false" />
14+
<activity
15+
android:name=".AddBook"
16+
android:exported="true" />
17+
<activity
18+
android:name=".MainActivity"
19+
android:exported="true">
1320
<intent-filter>
1421
<action android:name="android.intent.action.MAIN" />
1522

Room database/app/src/main/java/com/codeandcoke/mybooks/AddBook.java

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@
22

33
import static com.codeandcoke.mybooks.db.Constants.BOOKS;
44

5+
import android.app.Activity;
56
import android.app.AlertDialog;
7+
import android.content.Intent;
8+
import android.graphics.Bitmap;
9+
import android.graphics.drawable.BitmapDrawable;
10+
import android.net.Uri;
611
import android.os.Bundle;
12+
import android.provider.MediaStore;
713
import android.view.View;
814
import android.widget.Button;
915
import android.widget.EditText;
16+
import android.widget.ImageView;
1017
import android.widget.Toast;
1118

19+
import androidx.activity.result.ActivityResultLauncher;
20+
import androidx.activity.result.contract.ActivityResultContracts;
1221
import androidx.appcompat.app.AppCompatActivity;
1322
import androidx.room.Room;
1423

@@ -18,7 +27,9 @@
1827
public class AddBook extends AppCompatActivity implements View.OnClickListener {
1928

2029
private boolean modify;
21-
private int bookId;
30+
private String bookTitle;
31+
private ImageView bookImage;
32+
private String imageUri;
2233

2334
@Override
2435
protected void onCreate(Bundle savedInstanceState) {
@@ -28,20 +39,37 @@ protected void onCreate(Bundle savedInstanceState) {
2839
modify = getIntent().getBooleanExtra("modify", false);
2940
if (modify) {
3041
Book book = getIntent().getParcelableExtra("book");
31-
bookId = book.getId();
42+
bookTitle = book.getTitle();
3243
fillBookData(book);
3344
}
3445

35-
Button btSaveBook = findViewById(R.id.btSaveBook);
46+
Button btSaveBook = findViewById(R.id.save_book_button);
3647
btSaveBook.setOnClickListener(this);
48+
bookImage = findViewById(R.id.book_image);
49+
}
50+
51+
ActivityResultLauncher<Intent> galleryActivityResultLauncher = registerForActivityResult(
52+
new ActivityResultContracts.StartActivityForResult(),
53+
result -> {
54+
if (result.getResultCode() == Activity.RESULT_OK) {
55+
Uri uri = result.getData().getData();
56+
bookImage.setImageURI(uri);
57+
imageUri = uri.toString();
58+
}
59+
}
60+
);
61+
62+
public void setImage(View view) {
63+
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
64+
galleryActivityResultLauncher.launch(galleryIntent);
3765
}
3866

3967
private void fillBookData(Book book) {
40-
EditText etTitle = findViewById(R.id.etTitle);
41-
EditText etDescription = findViewById(R.id.etDescription);
42-
EditText etPublisher = findViewById(R.id.etPublisher);
43-
EditText etCategory = findViewById(R.id.etCategory);
44-
EditText etPageCount = findViewById(R.id.etPageCount);
68+
EditText etTitle = findViewById(R.id.book_title);
69+
EditText etDescription = findViewById(R.id.book_description);
70+
EditText etPublisher = findViewById(R.id.book_publisher);
71+
EditText etCategory = findViewById(R.id.book_category);
72+
EditText etPageCount = findViewById(R.id.book_page_count);
4573

4674
etTitle.setText(book.getTitle());
4775
etDescription.setText(book.getDescription());
@@ -52,19 +80,20 @@ private void fillBookData(Book book) {
5280

5381
@Override
5482
public void onClick(View view) {
55-
EditText etTitle = findViewById(R.id.etTitle);
56-
EditText etDescription = findViewById(R.id.etDescription);
57-
EditText etPublisher = findViewById(R.id.etPublisher);
58-
EditText etCategory = findViewById(R.id.etCategory);
59-
EditText etPageCount = findViewById(R.id.etPageCount);
83+
EditText etTitle = findViewById(R.id.book_title);
84+
EditText etDescription = findViewById(R.id.book_description);
85+
EditText etPublisher = findViewById(R.id.book_publisher);
86+
EditText etCategory = findViewById(R.id.book_category);
87+
EditText etPageCount = findViewById(R.id.book_page_count);
88+
ImageView bookImage = findViewById(R.id.book_image);
6089

6190
final Book book = new Book();
62-
book.setId(bookId);
6391
book.setTitle(etTitle.getText().toString());
6492
book.setDescription(etDescription.getText().toString());
6593
book.setPublisher(etPublisher.getText().toString());
6694
book.setCategory(etCategory.getText().toString());
6795
book.setPageCount(Integer.parseInt(etPageCount.getText().toString()));
96+
book.setImage(imageUri);
6897

6998
final AppDatabase db = Room.databaseBuilder(this, AppDatabase.class, BOOKS)
7099
.allowMainThreadQueries()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.codeandcoke.mybooks;
2+
3+
import androidx.appcompat.app.AppCompatActivity;
4+
5+
import android.os.Bundle;
6+
7+
public class BookDetailActivity extends AppCompatActivity {
8+
9+
@Override
10+
protected void onCreate(Bundle savedInstanceState) {
11+
super.onCreate(savedInstanceState);
12+
setContentView(R.layout.activity_book_detail);
13+
}
14+
}

Room database/app/src/main/java/com/codeandcoke/mybooks/MainActivity.java

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919

2020
import androidx.annotation.NonNull;
2121
import androidx.appcompat.app.AppCompatActivity;
22+
import androidx.recyclerview.widget.LinearLayoutManager;
23+
import androidx.recyclerview.widget.RecyclerView;
2224
import androidx.room.Room;
2325

26+
import com.codeandcoke.mybooks.adapter.BookAdapter;
2427
import com.codeandcoke.mybooks.db.AppDatabase;
2528
import com.codeandcoke.mybooks.model.Book;
2629

@@ -29,29 +32,35 @@
2932

3033
public class MainActivity extends AppCompatActivity {
3134

32-
private ArrayAdapter<Book> booksAdapter;
35+
private BookAdapter adapter;
3336
private List<Book> books;
3437

3538
@Override
3639
protected void onCreate(Bundle savedInstanceState) {
3740
super.onCreate(savedInstanceState);
3841
setContentView(R.layout.activity_main);
3942

40-
ListView lvBooks = findViewById(R.id.lvBooks);
4143
books = new ArrayList<>();
42-
booksAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, books);
43-
lvBooks.setAdapter(booksAdapter);
44-
registerForContextMenu(lvBooks);
44+
RecyclerView recyclerView = findViewById(R.id.book_list);
45+
recyclerView.setHasFixedSize(true);
46+
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
47+
recyclerView.setLayoutManager(layoutManager);
48+
adapter = new BookAdapter(books);
49+
recyclerView.setAdapter(adapter);
4550
}
4651

4752
@Override
4853
protected void onResume() {
4954
super.onResume();
5055

56+
loadBooks();
57+
}
58+
59+
private void loadBooks() {
5160
final AppDatabase db = Room.databaseBuilder(this, AppDatabase.class, BOOKS).allowMainThreadQueries().build();
5261
books.clear();
5362
books.addAll(db.bookDao().getAll());
54-
booksAdapter.notifyDataSetChanged();
63+
adapter.notifyDataSetChanged();
5564
}
5665

5766
@Override
@@ -71,7 +80,7 @@ public boolean onQueryTextChange(String newText) {
7180

7281
@Override
7382
public boolean onQueryTextSubmit(String query) {
74-
Toast.makeText(getApplicationContext(), "TextSbumit: " + query, Toast.LENGTH_LONG).show();
83+
Toast.makeText(getApplicationContext(), "TextSubmit: " + query, Toast.LENGTH_LONG).show();
7584
return true;
7685
}
7786
};
@@ -95,42 +104,6 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
95104
return super.onOptionsItemSelected(item);
96105
}
97106

98-
@Override
99-
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
100-
super.onCreateContextMenu(menu, v, menuInfo);
101-
getMenuInflater().inflate(R.menu.contextmenu, menu);
102-
}
103-
104-
@Override
105-
public boolean onContextItemSelected(@NonNull MenuItem item) {
106-
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
107-
final int position = menuInfo.position;
108-
final Book book = books.get(position);
109-
110-
if (item.getItemId() == R.id.recommend_book) {
111-
// TODO Recommend a book
112-
return true;
113-
} else if (item.getItemId() == R.id.modify_book) {
114-
modifyBook(book);
115-
return true;
116-
} else if (item.getItemId() == R.id.delete_book) {
117-
AlertDialog.Builder builder = new AlertDialog.Builder(this);
118-
builder.setMessage(R.string.are_you_sure)
119-
.setPositiveButton(R.string.yes, (dialogInterface, i) -> {
120-
deleteBook(book);
121-
// FIXME Refresco rápido
122-
books.remove(position);
123-
booksAdapter.notifyDataSetChanged();
124-
})
125-
.setNegativeButton(R.string.no, (dialogInterface, i) -> dialogInterface.dismiss());
126-
builder.create().show();
127-
128-
return true;
129-
}
130-
131-
return super.onContextItemSelected(item);
132-
}
133-
134107
private void modifyBook(Book book) {
135108
Intent intent = new Intent(this, AddBook.class);
136109
intent.putExtra("modify", true);
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package com.codeandcoke.mybooks.adapter;
2+
3+
import static com.codeandcoke.mybooks.db.Constants.BOOKS;
4+
5+
import android.content.Intent;
6+
import android.graphics.BitmapFactory;
7+
import android.net.Uri;
8+
import android.view.LayoutInflater;
9+
import android.view.View;
10+
import android.view.ViewGroup;
11+
import android.widget.Button;
12+
import android.widget.ImageView;
13+
import android.widget.TextView;
14+
15+
import androidx.annotation.NonNull;
16+
import androidx.recyclerview.widget.DividerItemDecoration;
17+
import androidx.recyclerview.widget.RecyclerView;
18+
import androidx.room.Room;
19+
20+
import com.codeandcoke.mybooks.BookDetailActivity;
21+
import com.codeandcoke.mybooks.R;
22+
import com.codeandcoke.mybooks.db.AppDatabase;
23+
import com.codeandcoke.mybooks.model.Book;
24+
25+
import java.util.List;
26+
27+
public class BookAdapter extends RecyclerView.Adapter<BookAdapter.TaskHolder> {
28+
29+
private List<Book> books;
30+
31+
public BookAdapter(List<Book> tasks) {
32+
this.books = tasks;
33+
}
34+
35+
@NonNull
36+
@Override
37+
public TaskHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
38+
View view = LayoutInflater.from(parent.getContext())
39+
.inflate(R.layout.book_item, parent, false);
40+
return new TaskHolder(view);
41+
}
42+
43+
@Override
44+
public void onBindViewHolder(@NonNull BookAdapter.TaskHolder holder, int position) {
45+
Book book = books.get(position);
46+
47+
if (book.getImage() != null) {
48+
holder.ivImage.setImageURI(Uri.parse(book.getImage()));
49+
}
50+
holder.tvTitle.setText(book.getTitle());
51+
holder.tvDescription.setText(book.getDescription());
52+
if (book.isRead()) {
53+
holder.doButton.setText("Leído");
54+
holder.parentView.setBackgroundColor(holder.parentView.getContext().getResources().getColor(android.R.color.holo_red_light));
55+
}
56+
else
57+
holder.doButton.setText("Sin leer");
58+
}
59+
60+
@Override
61+
public int getItemCount() {
62+
return books.size();
63+
}
64+
65+
public class TaskHolder extends RecyclerView.ViewHolder {
66+
67+
public ImageView ivImage;
68+
public TextView tvTitle;
69+
public TextView tvDescription;
70+
public Button doButton;
71+
public Button detailsButton;
72+
public View parentView;
73+
74+
public TaskHolder(@NonNull View view) {
75+
super(view);
76+
parentView = view;
77+
78+
ivImage = view.findViewById(R.id.book_item_image);
79+
tvTitle = view.findViewById(R.id.book_item_title);
80+
tvDescription = view.findViewById(R.id.book_item_description);
81+
doButton = view.findViewById(R.id.read_item_button);
82+
detailsButton = view.findViewById(R.id.details_item_button);
83+
84+
doButton.setOnClickListener(v -> doTask(view));
85+
detailsButton.setOnClickListener(v -> goToTaskDetails(view));
86+
}
87+
88+
private void doTask(View itemView) {
89+
int currentPosition = getAdapterPosition();
90+
Book book = books.get(currentPosition);
91+
book.setRead(!book.isRead());
92+
AppDatabase db = Room.databaseBuilder(itemView.getContext(), AppDatabase.class, BOOKS).allowMainThreadQueries().build();
93+
db.bookDao().update(book);
94+
if (book.isRead()) {
95+
doButton.setText("Reset");
96+
parentView.setBackgroundColor(itemView.getContext().getResources().getColor(android.R.color.holo_red_light));
97+
}
98+
else {
99+
doButton.setText("Leer");
100+
parentView.setBackgroundColor(itemView.getContext().getResources().getColor(android.R.color.white));
101+
}
102+
}
103+
104+
private void goToTaskDetails(View itemView) {
105+
Intent intent = new Intent(itemView.getContext(), BookDetailActivity.class);
106+
Book task = books.get(getBindingAdapterPosition());
107+
intent.putExtra("book_title", task.getTitle());
108+
itemView.getContext().startActivity(intent);
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)