mirror of
https://github.com/imcarlost/Android-Itunes-API.git
synced 2026-04-10 02:46:54 -04:00
+ Listview Adapter class
+ iTunes API response parser + Artists listview loader + Search functionality + Search timer logic
This commit is contained in:
@@ -3,20 +3,31 @@ package com.hakodev.androiditunesapi.activities;
|
|||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.constraint.ConstraintLayout;
|
import android.support.constraint.ConstraintLayout;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.anthonycr.grant.PermissionsManager;
|
import com.anthonycr.grant.PermissionsManager;
|
||||||
import com.anthonycr.grant.PermissionsResultAction;
|
import com.anthonycr.grant.PermissionsResultAction;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.hakodev.androiditunesapi.AndroidItunesAPI;
|
import com.hakodev.androiditunesapi.AndroidItunesAPI;
|
||||||
import com.hakodev.androiditunesapi.R;
|
import com.hakodev.androiditunesapi.R;
|
||||||
|
import com.hakodev.androiditunesapi.adapters.ArtistsListAdapter;
|
||||||
|
import com.hakodev.androiditunesapi.models.ItunesResponse;
|
||||||
|
import com.hakodev.androiditunesapi.models.Result;
|
||||||
import com.hakodev.androiditunesapi.util.Utils;
|
import com.hakodev.androiditunesapi.util.Utils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import okhttp3.Call;
|
import okhttp3.Call;
|
||||||
import okhttp3.Callback;
|
import okhttp3.Callback;
|
||||||
@@ -28,9 +39,17 @@ public class ArtistListActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private final static String TAG = "ArtistListActivity";
|
private final static String TAG = "ArtistListActivity";
|
||||||
private final static String SEARCH_URL = "https://itunes.apple.com/search?term=%1$s&country=US&entity=musicArtist&limit=10";
|
private final static String SEARCH_URL = "https://itunes.apple.com/search?term=%1$s&country=US&entity=musicArtist&limit=10";
|
||||||
|
private final static String[] DEMO_ARTISTS = {"Valentine", "Children", "Red"};
|
||||||
|
|
||||||
private OkHttpClient networkClient;
|
private OkHttpClient networkClient;
|
||||||
|
private ArtistsListAdapter artistsListAdapter;
|
||||||
|
private ArrayList<String> artistsList = new ArrayList<>();
|
||||||
|
|
||||||
private ConstraintLayout lytBase;
|
private ConstraintLayout lytBase;
|
||||||
|
private ListView listArtists;
|
||||||
|
private EditText txtArtistSearch;
|
||||||
|
|
||||||
|
private Timer keypressTimer = new Timer();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -40,6 +59,9 @@ public class ArtistListActivity extends AppCompatActivity {
|
|||||||
setupViews();
|
setupViews();
|
||||||
init();
|
init();
|
||||||
askForPermissions();
|
askForPermissions();
|
||||||
|
|
||||||
|
int randomArtistIndex = new Random().nextInt(DEMO_ARTISTS.length);
|
||||||
|
requestArtist(DEMO_ARTISTS[randomArtistIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -53,10 +75,40 @@ public class ArtistListActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private void setupViews() {
|
private void setupViews() {
|
||||||
lytBase = findViewById(R.id.lytBase);
|
lytBase = findViewById(R.id.lytBase);
|
||||||
|
listArtists = findViewById(R.id.listArtists);
|
||||||
|
txtArtistSearch = findViewById(R.id.txtArtistSearch);
|
||||||
|
txtArtistSearch.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable txt) {
|
||||||
|
keypressTimer.cancel();
|
||||||
|
keypressTimer = new Timer();
|
||||||
|
keypressTimer.schedule(
|
||||||
|
new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (txt.toString().length() > 3){
|
||||||
|
requestArtist(txt.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
networkClient = AndroidItunesAPI.getInstance().getNetworkClient();
|
networkClient = AndroidItunesAPI.getInstance().getNetworkClient();
|
||||||
|
artistsListAdapter = new ArtistsListAdapter(this, artistsList);
|
||||||
|
listArtists.setAdapter(artistsListAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void askForPermissions() {
|
private void askForPermissions() {
|
||||||
@@ -90,10 +142,26 @@ public class ArtistListActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull Call call, @NonNull final Response response) throws IOException {
|
public void onResponse(@NonNull Call call, @NonNull final Response response) throws IOException {
|
||||||
String res = response.body().string();
|
String body = response.body().string();
|
||||||
Log.w(TAG, res);
|
Log.w(TAG, body);
|
||||||
|
buildArtistsList(parseArtistsResponse(body));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> parseArtistsResponse(String body) {
|
||||||
|
ItunesResponse itunesResponse = new Gson().fromJson(body, ItunesResponse.class);
|
||||||
|
ArrayList<String> artistsNames = new ArrayList<>();
|
||||||
|
for (Result artist : itunesResponse.getResults()) {
|
||||||
|
artistsNames.add(artist.getArtistName());
|
||||||
|
}
|
||||||
|
return artistsNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildArtistsList(ArrayList<String> artists) {
|
||||||
|
artistsList.clear();
|
||||||
|
artistsList.addAll(artists);
|
||||||
|
runOnUiThread(() -> artistsListAdapter.notifyDataSetChanged());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.hakodev.androiditunesapi.adapters;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.hakodev.androiditunesapi.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class ArtistsListAdapter extends ArrayAdapter<String> {
|
||||||
|
private final Context context;
|
||||||
|
private final ArrayList<String> values;
|
||||||
|
|
||||||
|
public ArtistsListAdapter(Context context, ArrayList<String> values) {
|
||||||
|
super(context, R.layout.artists_list_adapter, values);
|
||||||
|
this.context = context;
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||||
|
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
if (convertView == null) {
|
||||||
|
if (inflater != null) {
|
||||||
|
convertView = inflater.inflate(R.layout.artists_list_adapter, parent, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextView textView = convertView.findViewById(R.id.lblArtistName);
|
||||||
|
ImageView imageView = convertView.findViewById(R.id.imgArtist);
|
||||||
|
textView.setText(values.get(position));
|
||||||
|
imageView.setImageResource(R.drawable.default_artist);
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,20 +5,20 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Response {
|
public class ItunesResponse {
|
||||||
|
|
||||||
@SerializedName("resultCount")
|
@SerializedName("resultCount")
|
||||||
@Expose
|
@Expose
|
||||||
private Long resultCount;
|
private int resultCount;
|
||||||
@SerializedName("results")
|
@SerializedName("results")
|
||||||
@Expose
|
@Expose
|
||||||
private List<Result> results = null;
|
private List<Result> results = null;
|
||||||
|
|
||||||
public Long getResultCount() {
|
public int getResultCount() {
|
||||||
return resultCount;
|
return resultCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResultCount(Long resultCount) {
|
public void setResultCount(int resultCount) {
|
||||||
this.resultCount = resultCount;
|
this.resultCount = resultCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 5.8 KiB |
@@ -5,7 +5,9 @@
|
|||||||
android:id="@+id/lytBase"
|
android:id="@+id/lytBase"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.hakodev.androiditunesapi.activities.ArtistListActivity">
|
tools:context="com.hakodev.androiditunesapi.activities.ArtistListActivity"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/txtArtistSearch"
|
android:id="@+id/txtArtistSearch"
|
||||||
@@ -24,13 +26,11 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/listView"
|
android:id="@+id/listArtists"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_margin="16dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:background="@color/colorAccent"
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|||||||
@@ -2,17 +2,14 @@
|
|||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="58dp"
|
||||||
android:layout_gravity="center_vertical">
|
android:layout_gravity="center_vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imgArtist"
|
android:id="@+id/imgArtist"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_margin="16dp"
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:contentDescription="@string/description_artists_image"
|
android:contentDescription="@string/description_artists_image"
|
||||||
android:src="@drawable/default_artist"
|
android:src="@drawable/default_artist"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
@@ -21,14 +18,12 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/lblArtistName"
|
android:id="@+id/lblArtistName"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_margin="16dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:textSize="18sp"
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@+id/imgArtist"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
<item name="android:textColor">@color/colorText</item>
|
<item name="android:textColor">@color/colorText</item>
|
||||||
<item name="android:textColorSecondary">@color/colorTextSecondary</item>
|
<item name="android:textColorSecondary">@color/colorTextSecondary</item>
|
||||||
<item name="android:textColorHint">@color/colorHintText</item>
|
<item name="android:textColorHint">@color/colorHintText</item>
|
||||||
|
|
||||||
|
<item name="colorControlNormal">@color/colorPrimary</item>
|
||||||
|
<item name="android:editTextColor">@color/colorText</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.NoActionBar">
|
<style name="AppTheme.NoActionBar">
|
||||||
|
|||||||
Reference in New Issue
Block a user