diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 6564d52..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml index 032061a..4b3c500 100644 --- a/app/app.iml +++ b/app/app.iml @@ -73,7 +73,9 @@ + + @@ -91,9 +93,16 @@ + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 7150d1a..df87752 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -24,4 +24,21 @@ dependencies { testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1' + + + // recycler view + compile "com.android.support:recyclerview-v7:23.0.0" + + // retrofit + compile 'com.squareup.retrofit:retrofit:1.9.0' + compile 'com.google.code.gson:gson:2.3.1' + + // rx + compile 'io.reactivex:rxandroid:1.0.1' + + // picasso + compile 'com.squareup.picasso:picasso:2.5.2' + + // butterknife + compile 'com.jakewharton:butterknife:7.0.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f8da696..634187d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,20 +1,21 @@ + package="cc.soham.rxblrdroid"> + + + android:theme="@style/AppTheme"> + android:theme="@style/AppTheme.NoActionBar"> - diff --git a/app/src/main/java/cc/soham/rxblrdroid/MainActivity.java b/app/src/main/java/cc/soham/rxblrdroid/MainActivity.java index c4bc9df..5791bb4 100644 --- a/app/src/main/java/cc/soham/rxblrdroid/MainActivity.java +++ b/app/src/main/java/cc/soham/rxblrdroid/MainActivity.java @@ -4,28 +4,37 @@ import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem; +import butterknife.Bind; +import butterknife.ButterKnife; +import butterknife.OnClick; + public class MainActivity extends AppCompatActivity { + @Bind(R.id.recyclerview) + RecyclerView recyclerView; + @Bind(R.id.toolbar) + Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + + ButterKnife.bind(this); + setSupportActionBar(toolbar); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + } - FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - } - }); + @OnClick(R.id.fab) + public void fabOnClick(View view) { + Snackbar.make(view, "Loading", Snackbar.LENGTH_LONG).show(); } @Override diff --git a/app/src/main/java/cc/soham/rxblrdroid/network/MusicAdapter.java b/app/src/main/java/cc/soham/rxblrdroid/network/MusicAdapter.java new file mode 100644 index 0000000..8df7972 --- /dev/null +++ b/app/src/main/java/cc/soham/rxblrdroid/network/MusicAdapter.java @@ -0,0 +1,55 @@ +package cc.soham.rxblrdroid.network; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.List; + +import butterknife.Bind; +import butterknife.ButterKnife; +import cc.soham.rxblrdroid.R; +import cc.soham.rxblrdroid.objects.Result; + +/** + * Created by sohammondal on 13/10/15. + * Adapts the music {@Code Result} class to our {@code RecyclerView} + */ +public class MusicAdapter extends RecyclerView.Adapter { + private List results; + + public MusicAdapter(List results) { + this.results = results; + } + + @Override + public MusicAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_music, null); + return new ViewHolder(itemLayoutView); + } + + @Override + public void onBindViewHolder(ViewHolder viewHolder, int position) { + viewHolder.track.setText(results.get(position).getArtistName() + ", " + results.get(position).getTrackName()); + viewHolder.time.setText(String.valueOf(results.get(position).getTrackTimeMillis())); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + @Bind(R.id.item_music_track) + public TextView track; + @Bind(R.id.item_music_time) + public TextView time; + + public ViewHolder(View itemLayoutView) { + super(itemLayoutView); + ButterKnife.bind(this, itemLayoutView); + } + } + + @Override + public int getItemCount() { + return results.size(); + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/soham/rxblrdroid/network/MusicApi.java b/app/src/main/java/cc/soham/rxblrdroid/network/MusicApi.java new file mode 100644 index 0000000..ce9e9ec --- /dev/null +++ b/app/src/main/java/cc/soham/rxblrdroid/network/MusicApi.java @@ -0,0 +1,40 @@ +package cc.soham.rxblrdroid.network; + +import cc.soham.rxblrdroid.objects.NetworkResponse; +import retrofit.Callback; +import retrofit.RestAdapter; +import retrofit.http.GET; +import retrofit.http.Query; +import rx.Observable; + +/** + * Created by sohammondal on 12/10/15. + * Handles all network operations + */ +public class MusicApi { + private static final String API_URL = "https://itunes.apple.com"; + private static MusicApiInterface sMusicApiInterface; + + public static MusicApiInterface getApi() { + if (sMusicApiInterface == null) { + sMusicApiInterface = null; + RestAdapter restAdapter = new RestAdapter.Builder() + .setEndpoint(API_URL) + .build(); + + sMusicApiInterface = restAdapter.create(MusicApiInterface.class); + } + return sMusicApiInterface; + } + + public interface MusicApiInterface { + @GET("/search?entity=musicVideo") + NetworkResponse getMusic(@Query("term") String term); + + @GET("/search?entity=musicVideo") + void getMusic(@Query("term") String term, Callback networkResponseCallback); + + @GET("/search?entity=musicVideo") + Observable getMusicObservable(@Query("term") String term); + } +} diff --git a/app/src/main/java/cc/soham/rxblrdroid/objects/NetworkResponse.java b/app/src/main/java/cc/soham/rxblrdroid/objects/NetworkResponse.java new file mode 100644 index 0000000..1fd9aec --- /dev/null +++ b/app/src/main/java/cc/soham/rxblrdroid/objects/NetworkResponse.java @@ -0,0 +1,58 @@ +package cc.soham.rxblrdroid.objects; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by sohammondal on 12/10/15. + * Represents the network response in {@code MusicApi} + */ +public class NetworkResponse { + + @SerializedName("resultCount") + @Expose + private Integer resultCount; + @SerializedName("results") + @Expose + private List results = new ArrayList(); + + /** + * + * @return + * The resultCount + */ + public Integer getResultCount() { + return resultCount; + } + + /** + * + * @param resultCount + * The resultCount + */ + public void setResultCount(Integer resultCount) { + this.resultCount = resultCount; + } + + /** + * + * @return + * The results + */ + public List getResults() { + return results; + } + + /** + * + * @param results + * The results + */ + public void setResults(List results) { + this.results = results; + } + +} \ No newline at end of file diff --git a/app/src/main/java/cc/soham/rxblrdroid/objects/Result.java b/app/src/main/java/cc/soham/rxblrdroid/objects/Result.java new file mode 100644 index 0000000..3ef8515 --- /dev/null +++ b/app/src/main/java/cc/soham/rxblrdroid/objects/Result.java @@ -0,0 +1,685 @@ +package cc.soham.rxblrdroid.objects; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * Created by sohammondal on 12/10/15. + * Represents a single result item in in {@code MusicApi} + */ +public class Result { + + @SerializedName("wrapperType") + @Expose + private String wrapperType; + @SerializedName("kind") + @Expose + private String kind; + @SerializedName("artistId") + @Expose + private Integer artistId; + @SerializedName("collectionId") + @Expose + private Integer collectionId; + @SerializedName("trackId") + @Expose + private Integer trackId; + @SerializedName("artistName") + @Expose + private String artistName; + @SerializedName("collectionName") + @Expose + private String collectionName; + @SerializedName("trackName") + @Expose + private String trackName; + @SerializedName("collectionCensoredName") + @Expose + private String collectionCensoredName; + @SerializedName("trackCensoredName") + @Expose + private String trackCensoredName; + @SerializedName("artistViewUrl") + @Expose + private String artistViewUrl; + @SerializedName("collectionViewUrl") + @Expose + private String collectionViewUrl; + @SerializedName("trackViewUrl") + @Expose + private String trackViewUrl; + @SerializedName("previewUrl") + @Expose + private String previewUrl; + @SerializedName("artworkUrl30") + @Expose + private String artworkUrl30; + @SerializedName("artworkUrl60") + @Expose + private String artworkUrl60; + @SerializedName("artworkUrl100") + @Expose + private String artworkUrl100; + @SerializedName("collectionPrice") + @Expose + private Double collectionPrice; + @SerializedName("trackPrice") + @Expose + private Double trackPrice; + @SerializedName("releaseDate") + @Expose + private String releaseDate; + @SerializedName("collectionExplicitness") + @Expose + private String collectionExplicitness; + @SerializedName("trackExplicitness") + @Expose + private String trackExplicitness; + @SerializedName("discCount") + @Expose + private Integer discCount; + @SerializedName("discNumber") + @Expose + private Integer discNumber; + @SerializedName("trackCount") + @Expose + private Integer trackCount; + @SerializedName("trackNumber") + @Expose + private Integer trackNumber; + @SerializedName("trackTimeMillis") + @Expose + private Integer trackTimeMillis; + @SerializedName("country") + @Expose + private String country; + @SerializedName("currency") + @Expose + private String currency; + @SerializedName("primaryGenreName") + @Expose + private String primaryGenreName; + @SerializedName("contentAdvisoryRating") + @Expose + private String contentAdvisoryRating; + @SerializedName("radioStationUrl") + @Expose + private String radioStationUrl; + + /** + * + * @return + * The wrapperType + */ + public String getWrapperType() { + return wrapperType; + } + + /** + * + * @param wrapperType + * The wrapperType + */ + public void setWrapperType(String wrapperType) { + this.wrapperType = wrapperType; + } + + /** + * + * @return + * The kind + */ + public String getKind() { + return kind; + } + + /** + * + * @param kind + * The kind + */ + public void setKind(String kind) { + this.kind = kind; + } + + /** + * + * @return + * The artistId + */ + public Integer getArtistId() { + return artistId; + } + + /** + * + * @param artistId + * The artistId + */ + public void setArtistId(Integer artistId) { + this.artistId = artistId; + } + + /** + * + * @return + * The collectionId + */ + public Integer getCollectionId() { + return collectionId; + } + + /** + * + * @param collectionId + * The collectionId + */ + public void setCollectionId(Integer collectionId) { + this.collectionId = collectionId; + } + + /** + * + * @return + * The trackId + */ + public Integer getTrackId() { + return trackId; + } + + /** + * + * @param trackId + * The trackId + */ + public void setTrackId(Integer trackId) { + this.trackId = trackId; + } + + /** + * + * @return + * The artistName + */ + public String getArtistName() { + return artistName; + } + + /** + * + * @param artistName + * The artistName + */ + public void setArtistName(String artistName) { + this.artistName = artistName; + } + + /** + * + * @return + * The collectionName + */ + public String getCollectionName() { + return collectionName; + } + + /** + * + * @param collectionName + * The collectionName + */ + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + /** + * + * @return + * The trackName + */ + public String getTrackName() { + return trackName; + } + + /** + * + * @param trackName + * The trackName + */ + public void setTrackName(String trackName) { + this.trackName = trackName; + } + + /** + * + * @return + * The collectionCensoredName + */ + public String getCollectionCensoredName() { + return collectionCensoredName; + } + + /** + * + * @param collectionCensoredName + * The collectionCensoredName + */ + public void setCollectionCensoredName(String collectionCensoredName) { + this.collectionCensoredName = collectionCensoredName; + } + + /** + * + * @return + * The trackCensoredName + */ + public String getTrackCensoredName() { + return trackCensoredName; + } + + /** + * + * @param trackCensoredName + * The trackCensoredName + */ + public void setTrackCensoredName(String trackCensoredName) { + this.trackCensoredName = trackCensoredName; + } + + /** + * + * @return + * The artistViewUrl + */ + public String getArtistViewUrl() { + return artistViewUrl; + } + + /** + * + * @param artistViewUrl + * The artistViewUrl + */ + public void setArtistViewUrl(String artistViewUrl) { + this.artistViewUrl = artistViewUrl; + } + + /** + * + * @return + * The collectionViewUrl + */ + public String getCollectionViewUrl() { + return collectionViewUrl; + } + + /** + * + * @param collectionViewUrl + * The collectionViewUrl + */ + public void setCollectionViewUrl(String collectionViewUrl) { + this.collectionViewUrl = collectionViewUrl; + } + + /** + * + * @return + * The trackViewUrl + */ + public String getTrackViewUrl() { + return trackViewUrl; + } + + /** + * + * @param trackViewUrl + * The trackViewUrl + */ + public void setTrackViewUrl(String trackViewUrl) { + this.trackViewUrl = trackViewUrl; + } + + /** + * + * @return + * The previewUrl + */ + public String getPreviewUrl() { + return previewUrl; + } + + /** + * + * @param previewUrl + * The previewUrl + */ + public void setPreviewUrl(String previewUrl) { + this.previewUrl = previewUrl; + } + + /** + * + * @return + * The artworkUrl30 + */ + public String getArtworkUrl30() { + return artworkUrl30; + } + + /** + * + * @param artworkUrl30 + * The artworkUrl30 + */ + public void setArtworkUrl30(String artworkUrl30) { + this.artworkUrl30 = artworkUrl30; + } + + /** + * + * @return + * The artworkUrl60 + */ + public String getArtworkUrl60() { + return artworkUrl60; + } + + /** + * + * @param artworkUrl60 + * The artworkUrl60 + */ + public void setArtworkUrl60(String artworkUrl60) { + this.artworkUrl60 = artworkUrl60; + } + + /** + * + * @return + * The artworkUrl100 + */ + public String getArtworkUrl100() { + return artworkUrl100; + } + + /** + * + * @param artworkUrl100 + * The artworkUrl100 + */ + public void setArtworkUrl100(String artworkUrl100) { + this.artworkUrl100 = artworkUrl100; + } + + /** + * + * @return + * The collectionPrice + */ + public Double getCollectionPrice() { + return collectionPrice; + } + + /** + * + * @param collectionPrice + * The collectionPrice + */ + public void setCollectionPrice(Double collectionPrice) { + this.collectionPrice = collectionPrice; + } + + /** + * + * @return + * The trackPrice + */ + public Double getTrackPrice() { + return trackPrice; + } + + /** + * + * @param trackPrice + * The trackPrice + */ + public void setTrackPrice(Double trackPrice) { + this.trackPrice = trackPrice; + } + + /** + * + * @return + * The releaseDate + */ + public String getReleaseDate() { + return releaseDate; + } + + /** + * + * @param releaseDate + * The releaseDate + */ + public void setReleaseDate(String releaseDate) { + this.releaseDate = releaseDate; + } + + /** + * + * @return + * The collectionExplicitness + */ + public String getCollectionExplicitness() { + return collectionExplicitness; + } + + /** + * + * @param collectionExplicitness + * The collectionExplicitness + */ + public void setCollectionExplicitness(String collectionExplicitness) { + this.collectionExplicitness = collectionExplicitness; + } + + /** + * + * @return + * The trackExplicitness + */ + public String getTrackExplicitness() { + return trackExplicitness; + } + + /** + * + * @param trackExplicitness + * The trackExplicitness + */ + public void setTrackExplicitness(String trackExplicitness) { + this.trackExplicitness = trackExplicitness; + } + + /** + * + * @return + * The discCount + */ + public Integer getDiscCount() { + return discCount; + } + + /** + * + * @param discCount + * The discCount + */ + public void setDiscCount(Integer discCount) { + this.discCount = discCount; + } + + /** + * + * @return + * The discNumber + */ + public Integer getDiscNumber() { + return discNumber; + } + + /** + * + * @param discNumber + * The discNumber + */ + public void setDiscNumber(Integer discNumber) { + this.discNumber = discNumber; + } + + /** + * + * @return + * The trackCount + */ + public Integer getTrackCount() { + return trackCount; + } + + /** + * + * @param trackCount + * The trackCount + */ + public void setTrackCount(Integer trackCount) { + this.trackCount = trackCount; + } + + /** + * + * @return + * The trackNumber + */ + public Integer getTrackNumber() { + return trackNumber; + } + + /** + * + * @param trackNumber + * The trackNumber + */ + public void setTrackNumber(Integer trackNumber) { + this.trackNumber = trackNumber; + } + + /** + * + * @return + * The trackTimeMillis + */ + public Integer getTrackTimeMillis() { + return trackTimeMillis; + } + + /** + * + * @param trackTimeMillis + * The trackTimeMillis + */ + public void setTrackTimeMillis(Integer trackTimeMillis) { + this.trackTimeMillis = trackTimeMillis; + } + + /** + * + * @return + * The country + */ + public String getCountry() { + return country; + } + + /** + * + * @param country + * The country + */ + public void setCountry(String country) { + this.country = country; + } + + /** + * + * @return + * The currency + */ + public String getCurrency() { + return currency; + } + + /** + * + * @param currency + * The currency + */ + public void setCurrency(String currency) { + this.currency = currency; + } + + /** + * + * @return + * The primaryGenreName + */ + public String getPrimaryGenreName() { + return primaryGenreName; + } + + /** + * + * @param primaryGenreName + * The primaryGenreName + */ + public void setPrimaryGenreName(String primaryGenreName) { + this.primaryGenreName = primaryGenreName; + } + + /** + * + * @return + * The contentAdvisoryRating + */ + public String getContentAdvisoryRating() { + return contentAdvisoryRating; + } + + /** + * + * @param contentAdvisoryRating + * The contentAdvisoryRating + */ + public void setContentAdvisoryRating(String contentAdvisoryRating) { + this.contentAdvisoryRating = contentAdvisoryRating; + } + + /** + * + * @return + * The radioStationUrl + */ + public String getRadioStationUrl() { + return radioStationUrl; + } + + /** + * + * @param radioStationUrl + * The radioStationUrl + */ + public void setRadioStationUrl(String radioStationUrl) { + this.radioStationUrl = radioStationUrl; + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 18bc94c..ce501d7 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,25 +1,34 @@ - - + - + - diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index c795559..caed088 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -1,14 +1,19 @@ + tools:context=".MainActivity" + tools:showIn="@layout/activity_main"> - + diff --git a/app/src/main/res/layout/item_music.xml b/app/src/main/res/layout/item_music.xml new file mode 100644 index 0000000..48c3c4b --- /dev/null +++ b/app/src/main/res/layout/item_music.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file