The Android platform offers media playback tools that can be used by your applications to build an interface between the user and their music resources. We’re going to build a fundamental music player application for Android in this tutorial series.

In this tutorial help’s how to implement online music player with notification and local screen music controls .

We used Sound Cloud Used Stream Songs in this tutorial .As per your requirement can replace with your own resources to stream songs .And We Used DMAudioStreamer library help you to integrate audio streaming in your application.

Get Started

Dependencies Required:

dependencies {
implementation 'com.github.dibakarece:dmaudiostreamer:v1.0.4'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.nineoldandroids:library:2.4.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.sothree.slidinguppanel:library:3.3.1'
implementation 'com.github.ohoussein.playpauseview:playpauseview:1.0.2'
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'com.android.volley:volley:1.1.0'
implementation 'de.hdodenhof:circleimageview:3.0.0'
}

1.Create Application Class

Create Application Used To Initialize Required Components On Launch of App

package in.androidhunt.musicDEmo;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
public class App extends Application {
public static final String TAG = App.class.getSimpleName();
public static final boolean ENCRYPTED = true;
public static volatile Handler applicationHandler = null;
private static App application;
private static Context mContext;
private static App mInstance;
private RequestQueue mRequestQueue;
public static Context getContext() {
return mContext;
}
public static synchronized App getInstance() {
return mInstance;
}
public static void initImageLoader(Context context) {
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
config.threadPriority(Thread.NORM_PRIORITY - 2);
config.denyCacheImageMultipleSizesInMemory();
config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
config.tasksProcessingOrder(QueueProcessingType.LIFO);
config.writeDebugLogs(); // Remove for release app
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config.build());
}
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
initImageLoader(getApplicationContext());
application = this;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
@Override
public void onTerminate() {
super.onTerminate();
application = null;
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
}
view raw App.java hosted with ❤ by GitHub

2.Creating Music Albums Activity:

In This activity we used to list music albums in Grid View which Show in the Flowing Code.

AlbumActivity.java

package in.androidhunt.musicDEmo;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.snackbar.Snackbar;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import in.androidhunt.musicDEmo.adapter.AlbumListAdapter;
import in.androidhunt.musicDEmo.model.Album;
public class AlbumsActivity extends AppCompatActivity implements AlbumListAdapter.OnItemClickListener {
private static final String TAG = AlbumsActivity.class.getSimpleName();
private static String url = "https://www.androidhunt.in/apps/json/playlist.php";
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@BindView(R.id.swipe_refresh)
SwipeRefreshLayout swiperefresh;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.avi)
ProgressBar progressBar;
@BindView(R.id.collapsing_toolbar)
CollapsingToolbarLayout collapsingToolbar;
@BindView(R.id.appbar)
AppBarLayout appBarLayout;
RequestQueue request;
private AlbumListAdapter adapter;
private List<Album> albumList;
@Override
protected void onCreate(Bundle savedInstanceState) {
supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_albums);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
initCollapsingToolbar();
swiperefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
if (!isNetworkAvailable()) {
swiperefresh.setRefreshing(false);
} else {
swiperefresh.setRefreshing(true);
OnLineMode();
}
}
});
albumList = new ArrayList<>();
adapter = new AlbumListAdapter(this, albumList);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
OnLineMode();
swiperefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
if (!isNetworkAvailable()) {
swiperefresh.setRefreshing(false);
} else {
swiperefresh.setRefreshing(true);
OnLineMode();
}
}
});
}
/**
* Adding few albums for testing
*/
public void OnLineMode() {
if (isNetworkAvailable()) {
showProgress();
OfflineMode();
request = Volley.newRequestQueue(this);
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
albumList.clear();
hideProgress();
Log.d(TAG, response.toString());
// This Is used store response to device acess it when user offline
SharedPreferences sharedPref = getSharedPreferences("SONGS", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.clear();
editor.putString("SONGS_1", response.toString());
editor.commit();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Album a = new Album(obj.getString("title"), obj.getString("detail"), obj.getString("image"), obj.getString("id"), obj.getString("status"));
albumList.add(a);
} catch (JSONException e) {
e.printStackTrace();
}
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
OnLineMode();
}
});
// Adding request to request queue
App.getInstance().addToRequestQueue(movieReq);
} else {
final Snackbar snackbar = Snackbar.make(findViewById(R.id.main_content), "No Internet Connection", Snackbar.LENGTH_LONG);
snackbar.setAction("Offline", new View.OnClickListener() {
@Override
public void onClick(View v) {
snackbar.dismiss();
}
});
snackbar.show();
hideProgress();
OfflineMode();
}
}
public void OfflineMode() {
albumList.clear();
SharedPreferences sharedPref = getSharedPreferences("SONGS", Context.MODE_PRIVATE);
String res = sharedPref.getString("SONGS_1", "");
try {
JSONArray response = new JSONArray(res);
for (int i = 0; i < response.length(); i++) {
JSONObject obj = response.getJSONObject(i);
Album a = new Album(obj.getString("title"), obj.getString("detail"), obj.getString("image"), obj.getString("id"), obj.getString("status"));
albumList.add(a);
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
private void initCollapsingToolbar() {
collapsingToolbar.setTitle(" ");
appBarLayout.setExpanded(true);
// hiding & showing the title when toolbar expanded & collapsed
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
collapsingToolbar.setTitle("Songs");
isShow = true;
} else if (isShow) {
collapsingToolbar.setTitle(" ");
isShow = false;
}
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//to hide indicators
void showProgress() {
progressBar.setVisibility(View.VISIBLE);
}
void hideProgress() {
progressBar.setVisibility(View.GONE);
swiperefresh.setRefreshing(false);
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
@Override
public void onDestroy() {
super.onDestroy();
finish();
}
@Override
public void onItemClick(View view, Album album) {
PlaylistActivity.navigate(this, view.findViewById(R.id.thumbnail), album);
}
/**
* Converting dp to pixel
*/
private int dpToPx(int dp) {
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view); // item position
int column = position % spanCount; // item column
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount) { // top edge
outRect.top = spacing;
}
outRect.bottom = spacing; // item bottom
} else {
outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position >= spanCount) {
outRect.top = spacing; // item top
}
}
}
}
}
view raw AlbumActivity.java hosted with ❤ by GitHub

Creating Model For Album Items

package in.androidhunt.musicDEmo.model;
/**
* Created by Lincoln on 18/05/16.
*/
public class Album {
private String name;
private String about;
private String thumbnail;
private String id;
private String status;
public Album() {
}
public Album(String name, String about, String thumbnail, String id, String status) {
this.name = name;
this.about = about;
this.thumbnail = thumbnail;
this.id = id;
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMusicDir() {
return about;
}
public void setMusicDir(String about) {
this.about = about;
}
public String getThumbnail() {
return thumbnail;
}
public void setThumbnail(String thumbnail) {
this.thumbnail = thumbnail;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
view raw Album.java hosted with ❤ by GitHub

Create Xml Designs For Above Activity

activity_albums.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:background="@drawable/jrntr"
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:expandedTitleTextAppearance="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_ablums" />
<ProgressBar
android:id="@+id/avi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyle"
android:visibility="visible"
android:layout_gravity="center"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
view raw activity_albums.xml hosted with ❤ by GitHub

content_albums.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="@+id/swipe_refresh"
android:layout_height="match_parent"
android:background="#E1E1E1"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
view raw content_albums.xml hosted with ❤ by GitHub

Creating Recycle View Adapter for Showing Albums in List

AlbumListAdapter.java

package in.androidhunt.musicDEmo.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import in.androidhunt.musicDEmo.R;
import in.androidhunt.musicDEmo.model.Album;
public class AlbumListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Album> albumList;
private Context context;
private OnItemClickListener onItemClickListener;
public AlbumListAdapter(Context context, List<Album> albumList) {
this.context = context;
this.albumList = albumList;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.album_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof ViewHolder) {
final Album m = albumList.get(position);
((ViewHolder) holder).title.setText(m.getName());
((ViewHolder) holder).gener.setText(m.getMusicDir());
Picasso.with(context).load(m.getThumbnail()).into(((ViewHolder) holder).imageView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Album source = albumList.get(position);
String status = source.getStatus();
if (status.contains("inactive")) {
String mesg = "Sorry Currently Un Available";
Toast.makeText(context, mesg, Toast.LENGTH_LONG).show();
} else {
onItemClickListener.onItemClick(v, source);
}
}
});
}
}
@Override
public int getItemCount() {
return albumList.size();
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(View view, Album album);
}
public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.thumbnail)
ImageView imageView;
@BindView(R.id.title)
TextView title;
@BindView(R.id.count)
TextView gener;
public ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
}
}
}

Creating Album List Item

album_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="@dimen/card_margin"
android:elevation="3dp"
card_view:cardCornerRadius="@dimen/card_album_radius">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="@dimen/album_cover_height"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitXY" />
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/thumbnail"
android:paddingLeft="@dimen/album_title_padding"
android:paddingRight="@dimen/album_title_padding"
android:paddingTop="@dimen/album_title_padding"
android:textColor="@color/album_title"
android:textSize="@dimen/album_title" />
<TextView
android:id="@+id/count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:paddingBottom="@dimen/songs_count_padding_bottom"
android:paddingLeft="@dimen/album_title_padding"
android:paddingRight="@dimen/album_title_padding"
android:textSize="@dimen/songs_count" />
<ImageView
android:id="@+id/overflow"
android:layout_width="@dimen/ic_album_overflow_width"
android:layout_height="@dimen/ic_album_overflow_height"
android:layout_alignParentRight="true"
android:layout_below="@+id/thumbnail"
android:layout_marginTop="@dimen/ic_album_overflow_margin_top"
android:scaleType="centerCrop"
android:src="@drawable/ic_more" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
view raw album_item.xml hosted with ❤ by GitHub

The Final Design Of Above Activity As Shown Below

Final Design of Album Activity

3.Creating Music Playlist Activity With All Music Controls

PlaylistActivity.java

package in.androidhunt.musicDEmo;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.session.PlaybackState;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.format.DateUtils;
import android.transition.Slide;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.view.ViewCompat;
import androidx.palette.graphics.Palette;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.ohoussein.playpause.PlayPauseView;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import butterknife.BindView;
import butterknife.ButterKnife;
import dm.audiostreamer.AudioStreamingManager;
import dm.audiostreamer.CurrentSessionCallback;
import dm.audiostreamer.Logger;
import dm.audiostreamer.MediaMetaData;
import in.androidhunt.musicDEmo.adapter.PlayListAdapter;
import in.androidhunt.musicDEmo.model.Album;
import in.androidhunt.musicDEmo.view.LineProgress;
import in.androidhunt.musicDEmo.view.Slider;
import in.androidhunt.musicDEmo.view.SquareImageView;
public class PlaylistActivity extends AppCompatActivity implements CurrentSessionCallback, View.OnClickListener, Slider.OnValueChangedListener {
@BindView(R.id.collapsing_toolbar_layout)
CollapsingToolbarLayout collapsingToolbarLayout;
@BindView(R.id.tool_bar)
Toolbar toolbar;
@BindView(R.id.playlist_layout)
RecyclerView playList;
@BindView(R.id.avi_loader)
ProgressBar avi;
@BindView(R.id.image_album)
SquareImageView albumImage;
@BindView(R.id.sliding_layout)
SlidingUpPanelLayout mLayout;
@BindView(R.id.btn_play)
PlayPauseView btn_play;
@BindView(R.id.image_songAlbumArt)
ImageView image_songAlbumArt;
@BindView(R.id.img_bottom_albArt)
ImageView img_bottom_albArt;
@BindView(R.id.image_songAlbumArtBlur)
ImageView image_songAlbumArtBlur;
@BindView(R.id.slidepanel_time_progress)
TextView time_progress_slide;
@BindView(R.id.slidepanel_time_total)
TextView time_total_slide;
@BindView(R.id.slidepanel_time_progress_bottom)
TextView time_progress_bottom;
@BindView(R.id.slidepanel_time_total_bottom)
TextView time_total_bottom;
@BindView(R.id.pgPlayPauseLayout)
RelativeLayout pgPlayPauseLayout;
@BindView(R.id.lineProgress)
LineProgress lineProgress;
@BindView(R.id.audio_progress_control)
Slider audioPg;
@BindView(R.id.btn_backward)
ImageView btn_backward;
@BindView(R.id.text_songName)
TextView text_songName;
@BindView(R.id.text_songAlb)
TextView text_songAlb;
@BindView(R.id.txt_bottom_SongName)
TextView txt_bottom_SongName;
@BindView(R.id.txt_bottom_SongAlb)
TextView txt_bottom_SongAlb;
@BindView(R.id.slideBottomView)
RelativeLayout slideBottomView;
@BindView(R.id.cover_mirror)
ImageView image_mirror;
private PlayListAdapter adapter;
private boolean isExpand = false;
private Context context;
@BindView(R.id.btn_forward)
ImageView btn_forward;
//For Implementation
private AudioStreamingManager streamingManager;
private MediaMetaData currentSong;
private List<MediaMetaData> listOfSongs = new ArrayList<MediaMetaData>();
private String title;
private String musicDir;
private String platList_Id;
private String albumImg;
private boolean isPlaylistAdded;
public static final String PLAYLIST_ID = "playlist_id";
public static final String MUSIC_DIR = "music_dir";
public static final String ALBUM_ART = "album_art";
public static final String ALBUM_NAME = "album_name";
@BindView(R.id.fab)
FloatingActionButton floatingActionButton;
@BindView(R.id.app_bar_layout)
AppBarLayout appBarLayout;
public static void navigate(AlbumsActivity albumsActivity, View viewById, Album album) {
String about = album.getMusicDir();
String imgurl = album.getThumbnail();
String title = album.getName();
String playlistid = album.getId();
Intent intent = new Intent(albumsActivity, PlaylistActivity.class);
intent.putExtra(PLAYLIST_ID, playlistid);
intent.putExtra(MUSIC_DIR, about);
intent.putExtra(ALBUM_ART, imgurl);
intent.putExtra(ALBUM_NAME, title);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(albumsActivity, viewById, imgurl);
ActivityCompat.startActivity(albumsActivity, intent, options.toBundle());
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.BaseTheme_playlist);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
initActivityTransitions();
super.onCreate(savedInstanceState);
setContentView(R.layout.playlist_activity);
ButterKnife.bind(this);
Intent i = getIntent();
title = i.getStringExtra(ALBUM_NAME);
musicDir = i.getStringExtra(MUSIC_DIR);
platList_Id = i.getStringExtra(PLAYLIST_ID);
albumImg = i.getStringExtra(ALBUM_ART);
//Used or Element View Transitions
ViewCompat.setTransitionName(appBarLayout, albumImg);
supportPostponeEnterTransition();
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
adapter = new PlayListAdapter(this, listOfSongs, title, musicDir);
collapsingToolbarLayout.setTitle(title);
collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(android.R.color.transparent));
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
playList.setLayoutManager(mLayoutManager);
playList.setItemAnimator(new DefaultItemAnimator());
playList.setAdapter(adapter);
Picasso.with(getBaseContext()).load(albumImg).into(albumImage);
Picasso.with(this).load(albumImg).into(albumImage, new Callback() {
@Override
public void onSuccess() {
Bitmap bitmap = ((BitmapDrawable) albumImage.getDrawable()).getBitmap();
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
public void onGenerated(Palette palette) {
applyPalette(palette);
}
});
}
@Override
public void onError() {
}
});
adapter.setOnClickListener(new PlayListAdapter.SetOnclickListner() {
@Override
public void onClickSong(MediaMetaData album, int postion) {
if (!isPlaylistAdded) {
streamingManager.setMediaList(listOfSongs);
isPlaylistAdded = true;
checkAlreadyPlaying();
streamingManager.setShowPlayerNotification(true);
streamingManager.setPendingIntentAct(getNotificationPendingIntent());
}
playSong(album);
}
});
ImageButton closeDrawer = findViewById(R.id.down_arrow);
closeDrawer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isExpand) {
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
}
}
});
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listOfSongs.size() > 0) {
MediaMetaData album = listOfSongs.get(0);
if (!isPlaylistAdded) {
streamingManager.setMediaList(listOfSongs);
isPlaylistAdded = true;
checkAlreadyPlaying();
streamingManager.setShowPlayerNotification(true);
streamingManager.setPendingIntentAct(getNotificationPendingIntent());
}
playSong(album);
}
}
});
this.context = PlaylistActivity.this;
configAudioStreamer();
uiInitialization();
onLoadPlaylist(platList_Id, albumImg);
checkAlreadyPlaying();
}
@Override
public void onResume() {
super.onResume();
checkAlreadyPlaying();
if (streamingManager.isPlaying()) {
btn_play.change(false, true);
} else {
btn_play.change(true, true);
}
}
public void onLoadPlaylist(String movie, final String img) {
if (isNetworkAvailable()) {
OfflineMode();
if (!movie.equals("")) {
avi.setVisibility(View.VISIBLE);
String songs = "https://api.soundcloud.com/playlists/" + movie + "?client_id=95f22ed54a5c297b1c41f72d713623ef";
JsonObjectRequest movieReq = new JsonObjectRequest(Request.Method.GET, songs,
null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
storeResponse(response.toString());
avi.setVisibility(View.GONE);
listOfSongs.clear();
try {
JSONArray obj = response.getJSONArray("tracks");
// Parsing json
for (int i = 0; i < obj.length(); i++) {
JSONObject media = obj.getJSONObject(i);
MediaMetaData mediaMetaData = new MediaMetaData();
mediaMetaData.setMediaAlbum(title);
mediaMetaData.setMediaArt(img);
mediaMetaData.setMediaArtist(musicDir);
String songUrl = media.getString("stream_url") + "?client_id=95f22ed54a5c297b1c41f72d713623ef";
String songtitle = media.getString("title").replaceAll(".mp3", "").replaceAll("[0-9]", "").replaceAll("\\[.*?\\]", "").replaceAll("-", "").replaceAll("_", "").replaceAll("\\.", "").replaceAll("\\p{P}", "").replaceAll("Kbps", "");
mediaMetaData.setMediaUrl(songUrl);
long duration = Long.parseLong(media.getString("duration"));
mediaMetaData.setMediaDuration(TimeUnit.MILLISECONDS.toSeconds(duration) + "");
mediaMetaData.setMediaTitle(songtitle);
mediaMetaData.setMediaId(songtitle);
listOfSongs.add(mediaMetaData);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
avi.setVisibility(View.GONE);
}
});
// Adding request to request queue
App.getInstance().addToRequestQueue(movieReq);
}
} else {
OfflineMode();
avi.setVisibility(View.GONE);
final Snackbar snackbar = Snackbar.make(findViewById(R.id.sliding_layout), "No Internet Connection", Snackbar.LENGTH_LONG);
snackbar.setAction("Offline", new View.OnClickListener() {
@Override
public void onClick(View v) {
snackbar.dismiss();
}
});
snackbar.show();
}
}
private void storeResponse(String response) {
SharedPreferences sharedPref = getSharedPreferences(title, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.clear();
editor.putString(title + "123", response);
editor.commit();
}
public void OfflineMode() {
listOfSongs.clear();
SharedPreferences sharedPref = getSharedPreferences(title, Context.MODE_PRIVATE);
String res = sharedPref.getString(title + "123", "");
try {
JSONObject response = new JSONObject(res);
JSONArray obj = response.getJSONArray("tracks");
for (int i = 0; i < obj.length(); i++) {
JSONObject media = obj.getJSONObject(i);
MediaMetaData mediaMetaData = new MediaMetaData();
mediaMetaData.setMediaAlbum(title);
mediaMetaData.setMediaArt(albumImg);
mediaMetaData.setMediaArtist(musicDir);
String songUrl = media.getString("stream_url") + "?client_id=bd6d136e05d880eea1bc0b1a7bcad42f";
String songtitle = media.getString("title").replaceAll(".mp3", "").replaceAll("[0-9]", "").replaceAll("\\[.*?\\]", "").replaceAll("-", "").replaceAll("_", "").replaceAll("\\.", "").replaceAll("\\p{P}", "").replaceAll("Kbps", "");
mediaMetaData.setMediaId(songtitle);
mediaMetaData.setMediaUrl(songUrl);
long duration = Long.parseLong(media.getString("duration"));
mediaMetaData.setMediaDuration(TimeUnit.MILLISECONDS.toSeconds(duration) + "");
mediaMetaData.setMediaTitle(songtitle);
listOfSongs.add(mediaMetaData);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
@Override
public boolean dispatchTouchEvent(MotionEvent motionEvent) {
try {
return super.dispatchTouchEvent(motionEvent);
} catch (NullPointerException e) {
return false;
}
}
private void initActivityTransitions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Slide transition = new Slide();
transition.excludeTarget(android.R.id.statusBarBackground, true);
getWindow().setEnterTransition(transition);
getWindow().setReturnTransition(transition);
}
}
private void applyPalette(Palette palette) {
int primaryDark = getResources().getColor(R.color.primary_dark);
int primary = getResources().getColor(R.color.primary);
collapsingToolbarLayout.setContentScrimColor(palette.getMutedColor(primary));
collapsingToolbarLayout.setStatusBarScrimColor(palette.getDarkMutedColor(primaryDark));
updateBackground(findViewById(R.id.fab), palette);
supportStartPostponedEnterTransition();
}
private void updateBackground(FloatingActionButton fab, Palette palette) {
int lightVibrantColor = palette.getLightVibrantColor(getResources().getColor(android.R.color.white));
int vibrantColor = palette.getVibrantColor(getResources().getColor(R.color.accent));
fab.setRippleColor(lightVibrantColor);
fab.setBackgroundTintList(ColorStateList.valueOf(vibrantColor));
}
private void uiInitialization() {
btn_backward.setOnClickListener(this);
btn_forward.setOnClickListener(this);
btn_play.setOnClickListener(this);
pgPlayPauseLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
return;
}
});
if (streamingManager.isPlaying()) {
btn_play.change(false, true);
} else {
btn_play.change(true, true);
}
slideBottomView.setVisibility(View.VISIBLE);
slideBottomView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
}
});
audioPg.setMax(0);
audioPg.setOnValueChangedListener(this);
mLayout.addPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
if (slideOffset == 0.0f) {
isExpand = false;
slideBottomView.setVisibility(View.VISIBLE);
// slideBottomView.getBackground().setAlpha(0);
} else if (slideOffset > 0.0f && slideOffset < 1.0f) {
// slideBottomView.getBackground().setAlpha((int) slideOffset * 255);
} else {
// slideBottomView.getBackground().setAlpha(100);
isExpand = true;
slideBottomView.setVisibility(View.GONE);
}
}
@Override
public void onPanelStateChanged(View panel, SlidingUpPanelLayout.PanelState previousState, SlidingUpPanelLayout.PanelState newState) {
if (SlidingUpPanelLayout.PanelState.EXPANDED == newState) {
isExpand = true;
} else if (SlidingUpPanelLayout.PanelState.COLLAPSED == newState) {
isExpand = false;
}
}
});
}
private void configAudioStreamer() {
streamingManager = AudioStreamingManager.getInstance(context);
//Set PlayMultiple 'true' if want to playing sequentially one by one songs
// and provide the list of songs else set it 'false'
streamingManager.setPlayMultiple(true);
// streamingManager.setMediaList(listOfSongs);
//If you want to show the Player Notification then set ShowPlayerNotification as true
//and provide the pending intent so that after click on notification it will redirect to an activity
}
@Override
public void onBackPressed() {
if (isExpand) {
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
} else {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onStart() {
super.onStart();
try {
if (streamingManager != null) {
streamingManager.subscribesCallBack(this);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onStop() {
try {
if (streamingManager != null) {
streamingManager.unSubscribeCallBack();
}
} catch (Exception e) {
e.printStackTrace();
}
super.onStop();
}
@Override
protected void onDestroy() {
try {
if (streamingManager != null) {
streamingManager.unSubscribeCallBack();
}
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
@Override
public void updatePlaybackState(int state) {
Logger.e("updatePlaybackState: ", "" + state);
switch (state) {
case PlaybackStateCompat.STATE_PLAYING:
pgPlayPauseLayout.setVisibility(View.INVISIBLE);
btn_play.change(false, true);
if (currentSong != null) {
currentSong.setPlayState(PlaybackStateCompat.STATE_PLAYING);
notifyAdapter(currentSong);
}
break;
case PlaybackStateCompat.STATE_PAUSED:
pgPlayPauseLayout.setVisibility(View.INVISIBLE);
btn_play.change(true, true);
if (currentSong != null) {
currentSong.setPlayState(PlaybackStateCompat.STATE_PAUSED);
notifyAdapter(currentSong);
}
break;
case PlaybackStateCompat.STATE_NONE:
currentSong.setPlayState(PlaybackStateCompat.STATE_NONE);
notifyAdapter(currentSong);
break;
case PlaybackStateCompat.STATE_STOPPED:
pgPlayPauseLayout.setVisibility(View.INVISIBLE);
btn_play.change(true, true);
audioPg.setValue(0);
if (currentSong != null) {
currentSong.setPlayState(PlaybackStateCompat.STATE_NONE);
notifyAdapter(currentSong);
}
break;
case PlaybackStateCompat.STATE_BUFFERING:
pgPlayPauseLayout.setVisibility(View.VISIBLE);
if (currentSong != null) {
btn_play.change(true, true);
currentSong.setPlayState(PlaybackStateCompat.STATE_NONE);
notifyAdapter(currentSong);
}
break;
}
}
@Override
public void playSongComplete() {
String timeString = "00.00";
time_total_bottom.setText(timeString);
time_total_slide.setText(timeString);
time_progress_bottom.setText(timeString);
time_progress_slide.setText(timeString);
lineProgress.setLineProgress(0);
audioPg.setValue(0);
}
@Override
public void currentSeekBarPosition(int progress) {
audioPg.setValue(progress);
setPGTime(progress);
}
@Override
public void playCurrent(int indexP, MediaMetaData currentAudio) {
showMediaInfo(currentAudio);
notifyAdapter(currentAudio);
}
@Override
public void playNext(int indexP, MediaMetaData CurrentAudio) {
showMediaInfo(CurrentAudio);
}
@Override
public void playPrevious(int indexP, MediaMetaData currentAudio) {
showMediaInfo(currentAudio);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_forward:
streamingManager.onSkipToNext();
break;
case R.id.btn_backward:
streamingManager.onSkipToPrevious();
break;
case R.id.btn_play:
if (currentSong != null) {
playPauseEvent(view);
}
break;
}
}
@Override
public void onValueChanged(int value) {
streamingManager.onSeekTo(value);
streamingManager.scheduleSeekBarUpdate();
}
private void notifyAdapter(MediaMetaData media) {
adapter.notifyPlayState(media);
}
private void playPauseEvent(View v) {
if (streamingManager.isPlaying()) {
streamingManager.onPause();
((PlayPauseView) v).change(true, true);
} else {
streamingManager.onPlay(currentSong);
((PlayPauseView) v).change(false, true);
}
}
private void playSong(MediaMetaData media) {
if (streamingManager != null) {
streamingManager.onPlay(media);
showMediaInfo(media);
}
}
private void showMediaInfo(MediaMetaData media) {
currentSong = media;
audioPg.setValue(0);
audioPg.setMin(0);
audioPg.setMax(Integer.valueOf(media.getMediaDuration()) * 1000);
setPGTime(0);
setMaxTime();
loadSongDetails(media);
}
private void checkAlreadyPlaying() {
if (streamingManager.isPlaying()) {
currentSong = streamingManager.getCurrentAudio();
if (currentSong != null) {
currentSong.setPlayState(streamingManager.mLastPlaybackState);
showMediaInfo(currentSong);
notifyAdapter(currentSong);
if (streamingManager.mLastPlaybackState == PlaybackState.STATE_BUFFERING) {
btn_play.change(true, true);
pgPlayPauseLayout.setVisibility(View.VISIBLE);
}
}
}
}
private void loadSongDetails(MediaMetaData metaData) {
text_songName.setText(metaData.getMediaTitle());
text_songAlb.setText(metaData.getMediaArtist());
txt_bottom_SongName.setText(metaData.getMediaTitle());
txt_bottom_SongAlb.setText(metaData.getMediaArtist());
Picasso.with(PlaylistActivity.this).load(metaData.getMediaArt()).into(img_bottom_albArt);
Picasso.with(PlaylistActivity.this).load(metaData.getMediaArt()).into(image_songAlbumArt);
Picasso.with(getBaseContext()).load(metaData.getMediaArt()).into(new Target() {
@Override
public void onBitmapFailed(Drawable arg0) {
// TODO Auto-generated method stub
}
@Override
public void onBitmapLoaded(Bitmap arg0, Picasso.LoadedFrom arg1) {
image_songAlbumArtBlur.setImageBitmap(ImageUtils.fastblur(arg0, 0.1f, 10));
int h = 300;
int s = 80;
image_mirror.setImageBitmap(ImageUtils.createReflectionBitmapForSingle(arg0, h, s));
}
@Override
public void onPrepareLoad(Drawable arg0) {
// TODO Auto-generated method stub
}
});
}
private void setPGTime(int progress) {
try {
String timeString = "00.00";
int linePG = 0;
currentSong = streamingManager.getCurrentAudio();
if (currentSong != null && progress != Long.parseLong(currentSong.getMediaDuration())) {
timeString = DateUtils.formatElapsedTime(progress / 1000);
Long audioDuration = Long.parseLong(currentSong.getMediaDuration());
linePG = (int) (((progress / 1000) * 100) / audioDuration);
}
time_progress_bottom.setText(timeString);
time_progress_slide.setText(timeString);
lineProgress.setLineProgress(linePG);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
private void setMaxTime() {
try {
String timeString = DateUtils.formatElapsedTime(Long.parseLong(currentSong.getMediaDuration()));
time_total_bottom.setText(timeString);
time_total_slide.setText(timeString);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
private PendingIntent getNotificationPendingIntent() {
Intent intent = new Intent(context, PlaylistActivity.class);
intent.putExtra(PLAYLIST_ID, platList_Id);
intent.putExtra(MUSIC_DIR, musicDir);
intent.putExtra(ALBUM_ART, albumImg);
intent.putExtra(ALBUM_NAME, title);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
}

Creating Custom View to Show Line Progress

LineProgress.java

/*
* This is the source code of DMAudioStreaming for Android v. 1.0.0.
* You should have received a copy of the license in this archive (see LICENSE).
* Copyright @Dibakar_Mistry(dibakar.ece@gmail.com), 2017.
*/
package in.androidhunt.musicDEmo.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class LineProgress extends View {
public int progress;
public Paint paint = new Paint();
public LineProgress(Context context) {
super(context);
}
public LineProgress(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LineProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint = new Paint();
paint.setColor(Color.TRANSPARENT);
canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);
paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawRect(0, 0, this.progress, this.getHeight(), paint);
}
public void setLineProgress(int pg) {
int wdt = this.getWidth();
this.progress = pg * (wdt / 100);
invalidate();
}
}
view raw LineProgress.java hosted with ❤ by GitHub

Creating Custom Seek Bar:

Slider.java

/*
* This is the source code of DMAudioStreaming for Android v. 1.0.0.
* You should have received a copy of the license in this archive (see LICENSE).
* Copyright @Dibakar_Mistry(dibakar.ece@gmail.com), 2017.
*/
package in.androidhunt.musicDEmo.view;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import com.nineoldandroids.view.ViewHelper;
import in.androidhunt.musicDEmo.R;
public class Slider extends CustomView {
private int backgroundColor = Color.parseColor("#000000");
private int backgroundColorLine = Color.parseColor("#000000");
private Ball ball;
private Bitmap bitmap;
private int max = 100;
private int min = 0;
private OnValueChangedListener onValueChangedListener;
private boolean placedBall = false;
private boolean press = false;
private int value = 0;
public Slider(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(attrs);
}
/**
* Convert Dp to Pixel
*/
public static int dpToPx(float dp, Resources resources) {
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
return (int) px;
}
public static int getRelativeTop(View myView) {
if (myView.getId() == android.R.id.content)
return myView.getTop();
else
return myView.getTop() + getRelativeTop((View) myView.getParent());
}
public static int getRelativeLeft(View myView) {
if (myView.getId() == android.R.id.content)
return myView.getLeft();
else
return myView.getLeft() + getRelativeLeft((View) myView.getParent());
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getMin() {
return min;
}
// GETERS & SETTERS
public void setMin(int min) {
this.min = min;
}
public OnValueChangedListener getOnValueChangedListener() {
return onValueChangedListener;
}
public void setOnValueChangedListener(
OnValueChangedListener onValueChangedListener) {
this.onValueChangedListener = onValueChangedListener;
}
public int getValue() {
return value;
}
public void setValue(final int value) {
if (placedBall == false)
post(new Runnable() {
@Override
public void run() {
setValue(value);
}
});
else {
this.value = value;
float division = (ball.xFin - ball.xIni) / max;
ViewHelper.setX(ball, value * division + getHeight() / 2 - ball.getWidth() / 2);
ball.changeBackground();
}
}
@Override
public void invalidate() {
ball.invalidate();
super.invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
isLastTouch = true;
if (isEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
if ((event.getX() <= getWidth() && event.getX() >= 0)) {
press = true;
// calculate value
int newValue = 0;
float division = (ball.xFin - ball.xIni) / (max - min);
if (event.getX() > ball.xFin) {
newValue = max;
} else if (event.getX() < ball.xIni) {
newValue = min;
} else {
newValue = min + (int) ((event.getX() - ball.xIni) / division);
}
if (value != newValue) {
value = newValue;
if (onValueChangedListener != null)
onValueChangedListener.onValueChanged(newValue);
}
// move ball indicator
float x = event.getX();
x = (x < ball.xIni) ? ball.xIni : x;
x = (x > ball.xFin) ? ball.xFin : x;
ViewHelper.setX(ball, x);
ball.changeBackground();
} else {
press = false;
isLastTouch = false;
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
press = false;
}
}
return true;
}
@Override
public void setBackgroundColor(int color) {
backgroundColor = color;
backgroundColorLine = makeLineDeselectColor();
if (isEnabled())
beforeBackground = backgroundColor;
}
/**
* Make a dark color to press effect
*
* @return
*/
protected int makeLineDeselectColor() {
int r = (this.backgroundColor >> 16) & 0xFF;
int g = (this.backgroundColor >> 8) & 0xFF;
int b = (this.backgroundColor >> 0) & 0xFF;
r = (r - 30 < 0) ? 0 : r - 30;
g = (g - 30 < 0) ? 0 : g - 30;
b = (b - 30 < 0) ? 0 : b - 30;
return Color.argb(128, r, g, b);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!placedBall) {
placeBall();
}
Paint paint = new Paint();
paint.setColor(backgroundColorLine);
paint.setStrokeWidth(dpToPx(3, getResources()));
canvas.drawLine(getHeight() / 2, getHeight() / 2, getWidth() - getHeight() / 2, getHeight() / 2, paint);
paint.setColor(backgroundColor);
float division = (ball.xFin - ball.xIni) / (max - min);
int value = this.value - min;
canvas.drawLine(getHeight() / 2, getHeight() / 2, value * division + getHeight() / 2, getHeight() / 2, paint);
if (press) {
paint.setColor(backgroundColor);
paint.setAntiAlias(true);
canvas.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2, getHeight() / 2, getHeight() / 4, paint);
}
invalidate();
}
// Set atributtes of XML to View
protected void setAttributes(AttributeSet attrs) {
setBackgroundResource(R.drawable.background_transparent);
// Set size of view
setMinimumHeight(dpToPx(48, getResources()));
setMinimumWidth(dpToPx(80, getResources()));
// Set background Color
// Color by resource
int bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML, "background", -1);
if (bacgroundColor != -1) {
setBackgroundColor(getResources().getColor(bacgroundColor));
} else {
// Color by hexadecimal
int background = attrs.getAttributeIntValue(ANDROIDXML, "background", -1);
if (background != -1)
setBackgroundColor(background);
}
min = attrs.getAttributeIntValue(MATERIALDESIGNXML, "min", 0);
max = attrs.getAttributeIntValue(MATERIALDESIGNXML, "max", 0);
value = attrs.getAttributeIntValue(MATERIALDESIGNXML, "value", min);
ball = new Ball(getContext());
LayoutParams params = new LayoutParams(dpToPx(15, getResources()), dpToPx(15, getResources()));
params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
ball.setLayoutParams(params);
addView(ball);
}
private void placeBall() {
ViewHelper.setX(ball, getHeight() / 2 - ball.getWidth() / 2);
ball.xIni = ViewHelper.getX(ball);
ball.xFin = getWidth() - getHeight() / 2 - ball.getWidth() / 2;
ball.xCen = getWidth() / 2 - ball.getWidth() / 2;
placedBall = true;
}
// Event when slider change value
public interface OnValueChangedListener {
public void onValueChanged(int value);
}
class Ball extends View {
float xIni, xFin, xCen;
public Ball(Context context) {
super(context);
changeBackground();
}
public void changeBackground() {
setBackgroundResource(R.drawable.background_checkbox);
LayerDrawable layer = (LayerDrawable) getBackground();
GradientDrawable shape = (GradientDrawable) layer.findDrawableByLayerId(R.id.shape_bacground);
shape.setColor(backgroundColor);
}
}
}
view raw Slider.java hosted with ❤ by GitHub

CustomView.java

/*
* This is the source code of DMAudioStreaming for Android v. 1.0.0.
* You should have received a copy of the license in this archive (see LICENSE).
* Copyright @Dibakar_Mistry(dibakar.ece@gmail.com), 2017.
*/
package in.androidhunt.musicDEmo.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
public class CustomView extends RelativeLayout {
final static String MATERIALDESIGNXML = "http://schemas.android.com/apk/res-auto";
final static String ANDROIDXML = "http://schemas.android.com/apk/res/android";
final int disabledBackgroundColor = Color.parseColor("#E2E2E2");
// Indicate if user touched this view the last time
public boolean isLastTouch = false;
int beforeBackground;
boolean animation = false;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
if (enabled)
setBackgroundColor(beforeBackground);
else
setBackgroundColor(disabledBackgroundColor);
invalidate();
}
@Override
protected void onAnimationStart() {
super.onAnimationStart();
animation = true;
}
@Override
protected void onAnimationEnd() {
super.onAnimationEnd();
animation = false;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (animation)
invalidate();
}
}
view raw CustomView.java hosted with ❤ by GitHub

Creating Custom Image View

SquareImageView.java

/*
* Copyright (C) 2015 Antonio Leiva
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package in.androidhunt.musicDEmo.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}
view raw SquareImageView.java hosted with ❤ by GitHub

Creating XML Designs For PlaylistActivity

playlist_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:sothree="http://schemas.android.com/apk/res-auto"
android:id="@+id/sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
sothree:umanoPanelHeight="?attr/actionBarSize"
sothree:umanoParalaxOffset="0dp"
sothree:umanoShadowHeight="4dp">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<in.androidhunt.musicDEmo.view.SquareImageView
android:id="@+id/image_album"
android:layout_width="match_parent"
android:layout_height="400dp"
android:adjustViewBounds="true"
android:background="@android:color/darker_gray"
android:scaleType="fitXY"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="24dp"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_dummy"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/playlist_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
style="@style/FabStyle"
app:layout_anchor="@id/app_bar_layout"
app:layout_anchorGravity="bottom|right|end" />
<ProgressBar
android:id="@+id/avi_loader"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:visibility="visible"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<include
android:id="@+id/include_sliding_panel_childtwo"
layout="@layout/include_slidingpanel_childtwo"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.sothree.slidinguppanel.SlidingUpPanelLayout>

include_slidingpanel_childtwo.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/dragView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_songAlbumArtBlur"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/bg_default_album_art" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageButton
android:id="@+id/down_arrow"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginTop="45dp"
android:layout_marginLeft="20dp"
android:gravity="start"
android:src="@drawable/ic_down_arow"
android:background="@drawable/ic_down_arow"
/>
<LinearLayout
android:id="@+id/layout_media_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:layout_marginTop="30dp"
android:padding="15dp">
<TextView
android:id="@+id/text_songName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My Fev Songs"
android:textColor="@android:color/white"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_songAlb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="My Fev Album"
android:textColor="@android:color/white"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<RelativeLayout
android:layout_width="240dp"
android:layout_height="380dp"
android:layout_below="@+id/layout_media_info"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp">
<LinearLayout
android:id="@+id/linear_layout_music_cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/image_songAlbumArt"
android:layout_width="@dimen/cover_width_height"
android:layout_height="250dp"
android:scaleType="fitXY"
/>
<ImageView
android:id="@+id/cover_mirror"
android:layout_width="@dimen/cover_width_height"
android:layout_height="@dimen/cover_mirror_height"
android:scaleType="fitXY"
android:layout_marginTop="@dimen/cover_mirror_margin_top"
/>
</LinearLayout>
</RelativeLayout>
<include
android:id="@+id/bottom_palyLayout"
layout="@layout/include_slidepanelchildtwo_bottomview"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_control_panel"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:orientation="vertical" />
<include
android:id="@+id/slideBottomView"
layout="@layout/include_slidepanelchildtwo_topviewtwo"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:visibility="invisible" />
</RelativeLayout>
</RelativeLayout>

include_slidepanelchildtwo_topviewtwo.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:playpauseview="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/md_blue_grey_100"
android:elevation="4dp"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_toLeftOf="@+id/rel_bottombar_moreicon"
android:elevation="4dp">
<ImageView
android:id="@+id/img_bottom_albArt"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:scaleType="centerCrop"
android:src="@drawable/bg_default_album_art">
</ImageView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<TextView
android:id="@+id/txt_bottom_SongName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="false"
android:freezesText="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/md_blue_grey_700"
android:textStyle="bold" />
<TextView
android:id="@+id/txt_bottom_SongAlb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/md_blue_grey_700"
android:textStyle="normal" />
</LinearLayout>
<in.androidhunt.musicDEmo.view.LineProgress
android:id="@+id/lineProgress"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_alignParentTop="true" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp"
android:gravity="center">
<TextView
android:id="@+id/slidepanel_time_progress_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:singleLine="true"
android:text="00.00"
android:textColor="@color/md_blue_grey_700"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:text="/"
android:textColor="@color/md_blue_grey_700"
android:textSize="14sp" />
<TextView
android:id="@+id/slidepanel_time_total_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:singleLine="true"
android:text="00.00"
android:textColor="@color/md_blue_grey_700"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<RelativeLayout
android:id="@+id/rel_bottombar_moreicon"
android:layout_width="96dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:visibility="gone">
<ImageView
android:id="@+id/bottombar_img_Favorite"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/bottombar_moreicon"
android:background="@drawable/bar_selector_white"
android:clickable="true"
android:scaleType="centerInside" />
<ImageView
android:id="@+id/bottombar_moreicon"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/bar_selector_white"
android:clickable="true"
android:scaleType="centerInside" />
</RelativeLayout>
</RelativeLayout>

include_slidepanelchildtwo_bottomview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:id="@+id/slidepanel_time_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:singleLine="true"
android:text="00.00"
android:textColor="@android:color/white"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:text="/"
android:textColor="@android:color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/slidepanel_time_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:singleLine="true"
android:text="00.00"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<in.androidhunt.musicDEmo.view.Slider
android:id="@+id/audio_progress_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/slidepanel_time_total"
android:layout_toRightOf="@+id/slidepanel_time_progress"
android:background="@android:color/white"
android:max="100"
android:min="0" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/btn_backward"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bar_selector_white"
android:gravity="center_vertical|right"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:src="@drawable/ic_rew_dark" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.ohoussein.playpause.PlayPauseView
android:id="@+id/btn_play"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:clickable="true"
android:stateListAnimator="@drawable/button_elevation"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/pgPlayPauseLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:visibility="invisible">
<ProgressBar
android:id="@+id/pgPlayPause"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?android:attr/progressBarStyle"
android:layout_centerInParent="true" />
</RelativeLayout>
</RelativeLayout>
<ImageView
android:id="@+id/btn_forward"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bar_selector_white"
android:gravity="center_vertical|right"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:src="@drawable/ic_fwd_dark" />
</LinearLayout>
</LinearLayout>

Creating Adapter For Music Playlist

PlayListAdapter.java

package in.androidhunt.musicDEmo.adapter;
import android.content.Context;
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 java.util.List;
import java.util.concurrent.TimeUnit;
import dm.audiostreamer.MediaMetaData;
import in.androidhunt.musicDEmo.R;
public class PlayListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<MediaMetaData> songsList;
private final String title;
private final String musicDir;
private final Context context;
private SetOnclickListner onClickListener;
public PlayListAdapter(Context context, List<MediaMetaData> songList, String title, String musicDir) {
this.songsList = songList;
this.title = title;
this.musicDir = musicDir;
this.context = context;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 0) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.albuminfo_item, parent, false);
return new ArtistViewHolder(v);
} else {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.song_item, parent, false);
return new ViewHolder(v);
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof ViewHolder) {
final MediaMetaData m = songsList.get(position - 1);
Long duration = Long.parseLong(m.getMediaDuration());
int milliseconds = (int) TimeUnit.SECONDS.toMillis(duration);
int minutes = (int) ((milliseconds / (1000 * 60)) % 60);
int seconds = (int) ((milliseconds / 1000) % 60);
if (Integer.toString(seconds).length() == 1) {
String sec = "0" + Integer.toString(seconds);
((ViewHolder) holder).duration.setText(Integer.toString(minutes) + ":" + sec);
} else {
((ViewHolder) holder).duration.setText(Integer.toString(minutes) + ":" + Integer.toString(seconds));
}
// Picasso.with(context).load(m.getThumbnailUrl()).error(R.mipmap.ic_launcher)
// .into(((ViewHolder) holder).imageView);
((ViewHolder) holder).songNo.setText(position + "");
String tit = m.getMediaTitle();
((ViewHolder) holder).title.setText(tit);
((ViewHolder) holder).itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onClickListener.onClickSong(m, position - 1);
}
});
} else {
((ArtistViewHolder) holder).title.setText(title);
((ArtistViewHolder) holder).artist.setText(musicDir);
((ArtistViewHolder) holder).songs.setText(songsList.size() + " songs");
}
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getItemCount() {
return songsList.size() + 1;
}
public void setOnClickListener(SetOnclickListner onClickListener) {
this.onClickListener = onClickListener;
}
public void notifyPlayState(MediaMetaData metaData) {
if (this.songsList != null && metaData != null) {
int index = this.songsList.indexOf(metaData);
//TODO SOMETIME INDEX RETURN -1 THOUGH THE OBJECT PRESENT IN THIS LIST
if (index == -1) {
for (int i = 0; i < this.songsList.size(); i++) {
if (this.songsList.get(i).getMediaId().equalsIgnoreCase(metaData.getMediaId())) {
index = i;
break;
}
}
}
if (index > 0 && index < this.songsList.size()) {
this.songsList.set(index, metaData);
}
}
notifyDataSetChanged();
}
public interface SetOnclickListner {
void onClickSong(MediaMetaData album, int postion);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView songNo;
TextView title;
TextView duration;
public ViewHolder(View v) {
super(v);
songNo = (TextView) v.findViewById(R.id.itemThumbnail_View);
title = (TextView) v.findViewById(R.id.itemVideoTitle_View);
duration = (TextView) v.findViewById(R.id.dur_ation);
}
}
public class ArtistViewHolder extends RecyclerView.ViewHolder {
TextView artist;
TextView title;
TextView songs;
public ArtistViewHolder(View v) {
super(v);
artist = (TextView) v.findViewById(R.id.artist_name);
title = (TextView) v.findViewById(R.id.album_name);
songs = (TextView) v.findViewById(R.id.s_info);
}
}
}
view raw PlayListAdapter.java hosted with ❤ by GitHub

Creating playlist item xml design

song_item.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:id="@+id/itemThumbnailViewContainer"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginRight="6dp"
android:orientation="horizontal">
<TextView
android:id="@+id/itemThumbnail_View"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="30dp"
android:text="1"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textStyle="normal"
/>
<TextView
android:id="@+id/itemVideoTitle_View"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="70dp"
android:layout_marginRight="5dp"
android:maxLines="1"
android:text="Pranamam pranamam"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@android:color/black"
android:textSize="16sp" />
<TextView
android:id="@+id/dur_ation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:singleLine="true"
android:text="1:20"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@android:color/black"
android:textSize="16sp" />
</RelativeLayout>
</FrameLayout>
view raw song_item.xml hosted with ❤ by GitHub

albuminfo_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white">
<TextView
android:id="@+id/album_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="20dp"
android:gravity="left|center"
android:maxLines="1"
android:text="Rabhasa"
android:textColor="@android:color/black"
android:textSize="20sp"
android:textStyle="normal" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/musicDir_View"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_below="@id/album_name"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:padding="5dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_artist_music" />
<TextView
android:id="@+id/artist_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/album_name"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/musicDir_View"
android:gravity="left|center"
android:maxLines="1"
android:text="Thaman SS"
android:textColor="@android:color/black"
android:textSize="12sp"
android:textStyle="normal" />
<TextView
android:id="@+id/s_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/artist_name"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@+id/musicDir_View"
android:gravity="left|center"
android:maxLines="1"
android:text="5 songs"
android:textColor="@android:color/black"
android:textSize="10sp"
android:textStyle="normal" />
</RelativeLayout>
view raw albuminfo_item.xml hosted with ❤ by GitHub

Creating Image Util Used For Mirror and Blur Effects

ImageUtil.java

package in.androidhunt.musicDEmo;
/**
* @author zhengken
* @time 2016/8/24 8:57
*/
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.util.Log;
public class ImageUtils {
public static Bitmap createReflectionBitmapForSingle(Bitmap src, int width, int height) {
final int w = src.getWidth();
final int h = src.getHeight();
Log.d("MainActivity", "reflection w = " + w);
Bitmap bitmap = Bitmap.createBitmap(w, height * h / width, Bitmap.Config.ARGB_8888);
Matrix m = new Matrix();
m.setScale(1, -1);
Bitmap t_bitmap = Bitmap.createBitmap(src, 0, h - (height * w / width), w, height * w / width, m, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(t_bitmap, 0, 0, paint);
Shader shader = new LinearGradient(0, 0, 0, height * h / width, 0x70ffffff,
0x00ffffff, Shader.TileMode.MIRROR);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));