Skip to content

Commit 3885ce7

Browse files
committed
Release 0.1
App complete with dark theme and anime api calls with advance details
1 parent a646c2e commit 3885ce7

50 files changed

Lines changed: 615 additions & 289 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ dependencies {
5858
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
5959

6060
implementation "org.apache.commons:commons-lang3:3.12.0"
61+
implementation 'com.squareup.picasso:picasso:2.8'
6162
}
9.01 KB
Loading

app/src/main/java/pmm/ignacio/theanimedatabase/Anime/AnimeService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ Call<AnimeChunk> ranking(
2525
@Query("offset") int offset);
2626

2727
@GET("anime/{id}")
28-
Call<AnimeDetails> animeDetails(@Path("id") int id);
28+
Call<AnimeDetails> animeDetails(
29+
@Header("Authorization") String authorization,
30+
@Path("id") int id,
31+
@Query("fields") String fields);
2932

3033
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package pmm.ignacio.theanimedatabase.Anime.data;
2+
3+
public class AlternativeTitles {
4+
public String en;
5+
public String ja;
6+
}

app/src/main/java/pmm/ignacio/theanimedatabase/Anime/data/Anime.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,11 @@
33
import com.google.gson.annotations.SerializedName;
44

55
public class Anime {
6+
public int id;
67
public String title;
78
@SerializedName("main_picture")
89
public AnimePicture mainPicture;
910

1011
}
1112

1213

13-
class AnimePicture {
14-
private String medium;
15-
private String large;
16-
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
package pmm.ignacio.theanimedatabase.Anime.data;
22

3+
import com.google.gson.annotations.SerializedName;
4+
35
public class AnimeDetails {
46
public String title;
7+
@SerializedName("main_picture")
8+
public AnimePicture mainPicture;
9+
@SerializedName("alternative_titles")
10+
public AlternativeTitles alternativeTitles;
11+
@SerializedName("start_date")
12+
public String startDate;
13+
@SerializedName("end_date")
14+
public String endDate;
15+
public String synopsis;
16+
public String rank;
17+
public String popularity;
18+
public String mean;
19+
public String status;
20+
@SerializedName("num_episodes")
21+
public int numEpisodes;
522

623
}
24+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package pmm.ignacio.theanimedatabase.Anime.data;
2+
3+
public class AnimePicture {
4+
public String medium;
5+
public String large;
6+
}
Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,105 @@
11
package pmm.ignacio.theanimedatabase;
22

3+
import static pmm.ignacio.theanimedatabase.MainActivity.API_URL;
4+
import static pmm.ignacio.theanimedatabase.MainActivity.authorization;
5+
36
import android.content.Intent;
47
import android.os.Bundle;
8+
import android.text.method.ScrollingMovementMethod;
9+
import android.util.Log;
10+
import android.widget.ImageView;
511
import android.widget.TextView;
612

13+
import androidx.annotation.NonNull;
714
import androidx.appcompat.app.AppCompatActivity;
815

16+
import java.util.Collections;
17+
18+
import com.squareup.picasso.Picasso;
19+
20+
import okhttp3.OkHttpClient;
21+
import okhttp3.Protocol;
22+
import pmm.ignacio.theanimedatabase.Anime.AnimeService;
23+
import pmm.ignacio.theanimedatabase.Anime.data.AnimeChunk;
24+
import pmm.ignacio.theanimedatabase.Anime.data.AnimeDetails;
25+
import pmm.ignacio.theanimedatabase.Anime.data.AnimeNode;
26+
import retrofit2.Call;
27+
import retrofit2.Callback;
28+
import retrofit2.Response;
29+
import retrofit2.Retrofit;
30+
import retrofit2.converter.gson.GsonConverterFactory;
31+
932
public class AnimeDetailsActivity extends AppCompatActivity {
1033
private static final String TAG = AnimeDetailsActivity.class.getName();
11-
public static final String NAME_KEY = "NAME";
34+
public static final String ID_ANIME = "ID_ANIME";
35+
private AnimeDetails _anime;
36+
private static final String FIELDS = "id,title,main_picture,alternative_titles,start_date,end_date,synopsis,mean,rank,popularity,num_list_users,num_scoring_users,nsfw,created_at,updated_at,media_type,status,genres,my_list_status,num_episodes,start_season,broadcast,source,rating,pictures";
1237

1338
@Override
1439
protected void onCreate(Bundle savedInstanceState) {
1540
super.onCreate(savedInstanceState);
1641
setContentView(R.layout.activity_anime_details);
17-
1842
Intent intent = getIntent();
19-
String name = intent.getStringExtra(NAME_KEY);
20-
TextView textView = findViewById(R.id.anime_detail_name);
21-
textView.setText(name);
43+
int id = intent.getIntExtra(ID_ANIME, 0);
44+
45+
// Retrofit API service
46+
OkHttpClient client = new OkHttpClient.Builder()
47+
.protocols(Collections.singletonList(Protocol.HTTP_1_1))
48+
.build();
49+
Retrofit retrofit = new Retrofit.Builder()
50+
.client(client)
51+
.baseUrl(API_URL)
52+
.addConverterFactory(GsonConverterFactory.create())
53+
.build();
54+
AnimeService _service = retrofit.create(AnimeService.class);
55+
56+
// Call API: Get anime details
57+
Call<AnimeDetails> call = _service.animeDetails(authorization, id, FIELDS);
58+
call.enqueue(new Callback<AnimeDetails>() {
59+
@Override
60+
public void onResponse(@NonNull Call<AnimeDetails> call, @NonNull Response<AnimeDetails> response) {
61+
if (response.isSuccessful()) {
62+
_anime = response.body();
63+
Log.d(TAG, "Anime details loaded from API");
64+
SetAnimeDetailsText();
65+
} else {
66+
Log.e(TAG, "Error loading anime, server responds: " + response.code());
67+
}
68+
}
69+
70+
@Override
71+
public void onFailure(@NonNull Call<AnimeDetails> call, @NonNull Throwable t) {
72+
Log.e(TAG, "Error calling API: ", t);
73+
}
74+
});
75+
76+
}
77+
78+
private void SetAnimeDetailsText() {
79+
// Set anime details textviews
80+
TextView anime_detail_name = findViewById(R.id.anime_detail_name);
81+
TextView anime_detail_alternative_en = findViewById(R.id.anime_detail_alternative_en);
82+
TextView anime_detail_alternative_ja = findViewById(R.id.anime_detail_alternative_ja);
83+
TextView anime_detail_start_date = findViewById(R.id.anime_detail_start_date);
84+
TextView anime_detail_end_date = findViewById(R.id.anime_detail_end_date);
85+
TextView anime_detail_status = findViewById(R.id.anime_detail_status);
86+
TextView anime_detail_rank = findViewById(R.id.anime_detail_rank);
87+
TextView anime_detail_mean = findViewById(R.id.anime_detail_mean);
88+
TextView anime_detail_popularity = findViewById(R.id.anime_detail_popularity);
89+
TextView anime_detail_synopsis = findViewById(R.id.anime_detail_synopsis);
90+
ImageView anime_detail_image = findViewById(R.id.anime_detail_image);
91+
92+
anime_detail_name.setText(_anime.title);
93+
anime_detail_alternative_en.setText(_anime.alternativeTitles.en);
94+
anime_detail_alternative_ja.setText(_anime.alternativeTitles.ja);
95+
anime_detail_start_date.setText(_anime.startDate);
96+
anime_detail_end_date.setText(_anime.endDate);
97+
anime_detail_status.setText(_anime.status);
98+
anime_detail_rank.setText(String.valueOf(_anime.rank));
99+
anime_detail_mean.setText(String.valueOf(_anime.mean));
100+
anime_detail_popularity.setText(String.valueOf(_anime.popularity));
101+
anime_detail_synopsis.setText(_anime.synopsis);
102+
anime_detail_synopsis.setMovementMethod(new ScrollingMovementMethod());
103+
Picasso.get().load(_anime.mainPicture.medium).into(anime_detail_image);
22104
}
23105
}

app/src/main/java/pmm/ignacio/theanimedatabase/MainActivity.java

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import android.os.Bundle;
66
import android.preference.PreferenceManager;
77
import android.util.Log;
8-
import android.widget.Button;
98

109
import androidx.annotation.NonNull;
1110
import androidx.appcompat.app.AppCompatActivity;
@@ -21,7 +20,6 @@
2120
import pmm.ignacio.theanimedatabase.Anime.data.AnimeChunk;
2221
import pmm.ignacio.theanimedatabase.Anime.data.AnimeNode;
2322
import pmm.ignacio.theanimedatabase.Anime.AnimeService;
24-
import pmm.ignacio.theanimedatabase.Anime.AnimeToken;
2523
import pmm.ignacio.theanimedatabase.RecyclerView.AnimeAdapter;
2624
import retrofit2.Call;
2725
import retrofit2.Callback;
@@ -33,13 +31,15 @@
3331
public class MainActivity extends AppCompatActivity {
3432

3533
private static final String TAG = MainActivity.class.getName();
36-
private static final String API_URL = "https://api.myanimelist.net/v2/";
34+
static final String API_URL = "https://api.myanimelist.net/v2/";
3735
private AnimeService _service;
3836
private int _offset = 0;
39-
private static final int LIMIT = 20;
37+
private static final int LIMIT = 50;
4038
private ArrayList<Anime> _anime = new ArrayList<Anime>();
4139
private RecyclerView.Adapter _adapter;
42-
private String authorization;
40+
static String authorization;
41+
RecyclerView recyclerView;
42+
4343

4444

4545
@Override
@@ -67,51 +67,57 @@ protected void onCreate(Bundle savedInstanceState) {
6767
.build();
6868
_service = retrofit.create(AnimeService.class);
6969

70-
// Load anime
71-
Button loadMoreButton = findViewById(R.id.load_more_button);
72-
loadMoreButton.setOnClickListener(v -> LoadChunk(_offset, LIMIT));
73-
74-
// Call API first time
75-
AddAnime(_offset, LIMIT);
76-
7770
// RecyclerView
78-
RecyclerView recyclerView = findViewById(R.id.recyclerView);
71+
recyclerView = findViewById(R.id.recyclerView);
7972
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
73+
recyclerView.setItemAnimator(null); // Avoid bug doing fast scrolling
74+
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
75+
@Override
76+
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
77+
super.onScrolled(recyclerView, dx, dy);
78+
if (!recyclerView.canScrollVertically(1)) {
79+
recyclerView.postDelayed(() -> {
80+
LoadChunk(_offset, LIMIT);
81+
}, 1000);
82+
}
83+
}
84+
});
8085
_adapter = new AnimeAdapter(_anime, anime -> {
8186
Intent intent = new Intent();
8287
intent.setClass(MainActivity.this, AnimeDetailsActivity.class);
83-
intent.putExtra(AnimeDetailsActivity.NAME_KEY, anime.title);
88+
intent.putExtra(AnimeDetailsActivity.ID_ANIME, anime.id);
8489
startActivity(intent);
8590
});
8691
recyclerView.setAdapter(_adapter);
8792

93+
// Call API first time
94+
LoadChunk(_offset, LIMIT);
95+
8896
}
8997
private void LoadChunk(int offset, int limit) {
90-
AddAnime(offset, limit);
91-
_adapter.notifyItemRangeInserted(offset, limit);
92-
_offset += LIMIT;
93-
}
94-
95-
private void AddAnime(int offset, int limit) {
9698
Log.i(TAG, "Loading anime from offset: " + offset + " limit: " + limit);
97-
Call<AnimeChunk> call = _service.listAnime(authorization,"one", offset, limit);
99+
Call<AnimeChunk> call = _service.listAnime(authorization,"piece", offset, limit);
98100
call.enqueue(new Callback<AnimeChunk>() {
99101
@Override
100102
public void onResponse(@NonNull Call<AnimeChunk> call, @NonNull Response<AnimeChunk> response) {
101103
if (response.isSuccessful()) {
102-
Log.i(TAG, "Anime received: " + (response.body() != null ? response.body().data.size() : 0));
104+
int count = response.body() != null ? response.body().data.size() : 0;
105+
Log.i(TAG, "Anime received: " + count);
103106
for (AnimeNode a : response.body().data) {
104107
// Add anime to the arraylist
105108
_anime.add(a.node);
106109
Log.d(TAG, "Anime: " + a.node.title);
107110
}
111+
// Notify adapter
112+
recyclerView.post(() -> _adapter.notifyItemRangeInserted(_offset, count));
113+
_offset += count;
108114
} else {
109115
Log.e(TAG, "Error loading anime, server responds: " + response.code());
110116
}
111117
}
112118

113119
@Override
114-
public void onFailure(Call<AnimeChunk> call, Throwable t) {
120+
public void onFailure(@NonNull Call<AnimeChunk> call, @NonNull Throwable t) {
115121
Log.e(TAG, "Error calling API: ", t);
116122
}
117123
});

app/src/main/java/pmm/ignacio/theanimedatabase/RecyclerView/AnimeAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ public void onBindViewHolder(AnimeViewHolder holder, int position) {
4242

4343
@Override
4444
public int getItemCount() {
45-
return 0;
45+
return _animeList.size();
4646
}
4747
}

0 commit comments

Comments
 (0)