Initial commit retro music app

This commit is contained in:
h4h13 2018-07-27 18:37:33 +05:30
parent ab332473bc
commit fe890632fd
932 changed files with 83126 additions and 0 deletions

View file

@ -0,0 +1,41 @@
package code.name.monkey.retromusic.misc;
import android.support.design.widget.AppBarLayout;
/**
* @author Hemanth S (h4h13).
* https://stackoverflow.com/a/33891727
*/
public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
private State mCurrentState = State.IDLE;
@Override
public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (i == 0) {
if (mCurrentState != State.EXPANDED) {
onStateChanged(appBarLayout, State.EXPANDED);
}
mCurrentState = State.EXPANDED;
} else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
if (mCurrentState != State.COLLAPSED) {
onStateChanged(appBarLayout, State.COLLAPSED);
}
mCurrentState = State.COLLAPSED;
} else {
if (mCurrentState != State.IDLE) {
onStateChanged(appBarLayout, State.IDLE);
}
mCurrentState = State.IDLE;
}
}
public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
public enum State {
EXPANDED,
COLLAPSED,
IDLE
}
}

View file

@ -0,0 +1,237 @@
package code.name.monkey.retromusic.misc;
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.
*/
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
/**
* Implementation of {@link android.support.v4.view.PagerAdapter} that
* uses a {@link Fragment} to manage each page. This class also handles
* saving and restoring of fragment's state.
* <p/>
* <p>This version of the pager is more useful when there are a large number
* of pages, working more like a list view. When pages are not visible to
* the user, their entire fragment may be destroyed, only keeping the saved
* state of that fragment. This allows the pager to hold on to much less
* memory associated with each visited page as compared to
* {@link FragmentPagerAdapter} at the cost of potentially more overhead when
* switching between pages.
* <p/>
* <p>When using FragmentPagerAdapter the host ViewPager must have a
* valid ID set.</p>
* <p/>
* <p>Subclasses only need to implement {@link #getItem(int)}
* and {@link #getCount()} to have a working adapter.
* <p/>
* <p>Here is an example implementation of a pager containing fragments of
* lists:
* <p/>
* {@sample development/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentStatePagerSupport.java
* complete}
* <p/>
* <p>The <code>R.layout.fragment_pager</code> resource of the top-level fragment is:
* <p/>
* {@sample development/samples/Support13Demos/res/layout/fragment_pager.xml
* complete}
* <p/>
* <p>The <code>R.layout.fragment_pager_list</code> resource containing each
* individual fragment's layout is:
* <p/>
* {@sample development/samples/Support13Demos/res/layout/fragment_pager_list.xml
* complete}
*/
public abstract class CustomFragmentStatePagerAdapter extends android.support.v4.view.PagerAdapter {
public static final String TAG = CustomFragmentStatePagerAdapter.class.getSimpleName();
private static final boolean DEBUG = false;
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
private Fragment mCurrentPrimaryItem = null;
public CustomFragmentStatePagerAdapter(FragmentManager fm) {
mFragmentManager = fm;
}
/**
* Return the Fragment associated with a specified position.
*/
public abstract Fragment getItem(int position);
@Override
public void startUpdate(ViewGroup container) {
}
@NonNull
@Override
public Object instantiateItem(ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);
if (f != null) {
return f;
}
}
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
Fragment fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
if (mSavedState.size() > position) {
Fragment.SavedState fss = mSavedState.get(position);
if (fss != null) {
fragment.setInitialSavedState(fss);
}
}
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
mCurTransaction.add(container.getId(), fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object;
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
+ " v=" + ((Fragment) object).getView());
while (mSavedState.size() <= position) {
mSavedState.add(null);
}
mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
mFragments.set(position, null);
mCurTransaction.remove(fragment);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
@Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() == view;
}
@Override
public Parcelable saveState() {
Bundle state = null;
if (mSavedState.size() > 0) {
state = new Bundle();
Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
mSavedState.toArray(fss);
state.putParcelableArray("states", fss);
}
for (int i = 0; i < mFragments.size(); i++) {
Fragment f = mFragments.get(i);
if (f != null && f.isAdded()) {
if (state == null) {
state = new Bundle();
}
String key = "f" + i;
mFragmentManager.putFragment(state, key, f);
}
}
return state;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
if (state != null) {
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
mFragments.clear();
if (fss != null) {
for (int i = 0; i < fss.length; i++) {
mSavedState.add((Fragment.SavedState) fss[i]);
}
}
Iterable<String> keys = bundle.keySet();
for (String key : keys) {
if (key.startsWith("f")) {
int index = Integer.parseInt(key.substring(1));
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
while (mFragments.size() <= index) {
mFragments.add(null);
}
f.setMenuVisibility(false);
mFragments.set(index, f);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
public Fragment getFragment(int position) {
if (position < mFragments.size() && position >= 0) {
return mFragments.get(position);
}
return null;
}
}

View file

@ -0,0 +1,90 @@
package code.name.monkey.retromusic.misc;
import android.app.Dialog;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.ref.WeakReference;
public abstract class DialogAsyncTask<Params, Progress, Result> extends WeakContextAsyncTask<Params, Progress, Result> {
private final int delay;
private WeakReference<Dialog> dialogWeakReference;
private boolean supposedToBeDismissed;
public DialogAsyncTask(Context context) {
this(context, 0);
}
public DialogAsyncTask(Context context, int showDelay) {
super(context);
this.delay = showDelay;
dialogWeakReference = new WeakReference<>(null);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (delay > 0) {
new Handler().postDelayed(this::initAndShowDialog, delay);
} else {
initAndShowDialog();
}
}
private void initAndShowDialog() {
Context context = getContext();
if (!supposedToBeDismissed && context != null) {
Dialog dialog = createDialog(context);
dialogWeakReference = new WeakReference<>(dialog);
dialog.show();
}
}
@SuppressWarnings("unchecked")
@Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
Dialog dialog = getDialog();
if (dialog != null) {
onProgressUpdate(dialog, values);
}
}
@SuppressWarnings("unchecked")
protected void onProgressUpdate(@NonNull Dialog dialog, Progress... values) {
}
@Nullable
protected Dialog getDialog() {
return dialogWeakReference.get();
}
@Override
protected void onCancelled(Result result) {
super.onCancelled(result);
tryToDismiss();
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
tryToDismiss();
}
private void tryToDismiss() {
supposedToBeDismissed = true;
try {
Dialog dialog = getDialog();
if (dialog != null)
dialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
protected abstract Dialog createDialog(@NonNull Context context);
}

View file

@ -0,0 +1,62 @@
package code.name.monkey.retromusic.misc;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class LagTracker {
private static Map<String, Long> mMap;
private static LagTracker mSingleton;
private boolean mEnabled = true;
private LagTracker() {
mMap = new HashMap();
}
public static LagTracker get() {
if (mSingleton == null) {
mSingleton = new LagTracker();
}
return mSingleton;
}
private void print(String str, long j) {
long toMillis = TimeUnit.NANOSECONDS.toMillis(j);
Log.d("LagTracker", "[" + str + " completed in]: " + j + " ns (" + toMillis + "ms, " + TimeUnit.NANOSECONDS.toSeconds(j) + "s)");
}
public LagTracker disable() {
this.mEnabled = false;
return this;
}
public LagTracker enable() {
this.mEnabled = true;
return this;
}
public void end(String str) {
long nanoTime = System.nanoTime();
if (this.mEnabled) {
if (mMap.containsKey(str)) {
print(str, nanoTime - mMap.get(str).longValue());
mMap.remove(str);
return;
}
throw new IllegalStateException("No start time found for " + str);
} else if (!mMap.isEmpty()) {
mMap.clear();
}
}
public void start(String str) {
long nanoTime = System.nanoTime();
if (this.mEnabled) {
mMap.put(str, Long.valueOf(nanoTime));
} else if (!mMap.isEmpty()) {
mMap.clear();
}
}
}

View file

@ -0,0 +1,110 @@
package code.name.monkey.retromusic.misc;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;
/*Don't delete even if its not showing not using*/
public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
private static final String TAG = "ScrollingFABBehavior";
Handler mHandler;
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
if (mHandler == null)
mHandler = new Handler();
mHandler.postDelayed(() -> {
child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
Log.d("FabAnim", "startHandler()");
}, 1000);
}
@Override
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View target,
int dxConsumed,
int dyConsumed,
int dxUnconsumed,
int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
//child -> Floating Action Button
if (dyConsumed > 0) {
Log.d("Scrolling", "Up");
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
int fab_bottomMargin = layoutParams.bottomMargin;
child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start();
} else if (dyConsumed < 0) {
Log.d("Scrolling", "down");
child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
}
}
@Override
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View directTargetChild,
@NonNull View target,
int nestedScrollAxes) {
if (mHandler != null) {
mHandler.removeMessages(0);
Log.d("Scrolling", "stopHandler()");
}
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
}
/*extends FloatingActionButton.Behavior {
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(@NonNull final CoordinatorLayout coordinatorLayout,
@NonNull final FloatingActionButton child,
@NonNull final View directTargetChild,
@NonNull final View target,
final int nestedScrollAxes) {
// Ensure we react to vertical scrolling
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
|| super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
@Override
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View target,
int dxConsumed,
int dyConsumed,
int dxUnconsumed,
int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed,
dyUnconsumed);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide();
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
}*/

View file

@ -0,0 +1,26 @@
package code.name.monkey.retromusic.misc;
import android.animation.Animator;
public abstract class SimpleAnimatorListener implements Animator.AnimatorListener {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}

View file

@ -0,0 +1,21 @@
package code.name.monkey.retromusic.misc;
import android.widget.SeekBar;
public abstract class SimpleOnSeekbarChangeListener implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}

View file

@ -0,0 +1,50 @@
package code.name.monkey.retromusic.misc;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import code.name.monkey.retromusic.R;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class UpdateToastMediaScannerCompletionListener implements MediaScannerConnection.OnScanCompletedListener {
private final String[] toBeScanned;
private final String scannedFiles;
private final String couldNotScanFiles;
private final WeakReference<Activity> activityWeakReference;
private int scanned = 0;
private int failed = 0;
private Toast toast;
@SuppressLint("ShowToast")
public UpdateToastMediaScannerCompletionListener(Activity activity, String[] toBeScanned) {
this.toBeScanned = toBeScanned;
scannedFiles = activity.getString(R.string.scanned_files);
couldNotScanFiles = activity.getString(R.string.could_not_scan_files);
toast = Toast.makeText(activity.getApplicationContext(), "", Toast.LENGTH_SHORT);
activityWeakReference = new WeakReference<>(activity);
}
@Override
public void onScanCompleted(final String path, final Uri uri) {
Activity activity = activityWeakReference.get();
if (activity != null) {
activity.runOnUiThread(() -> {
if (uri == null) {
failed++;
} else {
scanned++;
}
String text = " " + String.format(scannedFiles, scanned, toBeScanned.length) + (failed > 0 ? " " + String.format(couldNotScanFiles, failed) : "");
toast.setText(text);
toast.show();
});
}
}
}

View file

@ -0,0 +1 @@
package code.name.monkey.retromusic.misc; import android.content.Context; import android.os.AsyncTask; import android.support.annotation.Nullable; import java.lang.ref.WeakReference; public abstract class WeakContextAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { private WeakReference<Context> contextWeakReference; public WeakContextAsyncTask(Context context) { contextWeakReference = new WeakReference<>(context); } @Nullable protected Context getContext() { return contextWeakReference.get(); } }

View file

@ -0,0 +1,72 @@
package code.name.monkey.retromusic.misc;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
/**
* <a href="http://code.google.com/p/android/issues/detail?id=14944">Issue
* 14944</a>
*
* @author Alexander Blom
*/
public abstract class WrappedAsyncTaskLoader<D> extends AsyncTaskLoader<D> {
private D mData;
/**
* Constructor of <code>WrappedAsyncTaskLoader</code>
*
* @param context The {@link Context} to use.
*/
public WrappedAsyncTaskLoader(Context context) {
super(context);
}
/**
* {@inheritDoc}
*/
@Override
public void deliverResult(D data) {
if (!isReset()) {
this.mData = data;
super.deliverResult(data);
} else {
// An asynchronous query came in while the loader is stopped
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onStartLoading() {
super.onStartLoading();
if (this.mData != null) {
deliverResult(this.mData);
} else if (takeContentChanged() || this.mData == null) {
forceLoad();
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onStopLoading() {
super.onStopLoading();
// Attempt to cancel the current load task if possible
cancelLoad();
}
/**
* {@inheritDoc}
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
this.mData = null;
}
}