Fix animations, aligment
This commit is contained in:
parent
caed1ee47c
commit
a5e349380c
14 changed files with 858 additions and 26 deletions
|
@ -121,7 +121,8 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
||||
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let {
|
||||
artistDetailsPresenter.loadArtist(it)
|
||||
artistCoverContainer?.transitionName = "${getString(R.string.transition_artist_image)}_$it"
|
||||
val name = "${getString(R.string.transition_artist_image)}_$it"
|
||||
artistCoverContainer?.transitionName = name
|
||||
}
|
||||
} else {
|
||||
finish()
|
||||
|
|
|
@ -8,11 +8,9 @@ import android.content.SharedPreferences
|
|||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||
import code.name.monkey.retromusic.fragments.mainactivity.LibraryFragment
|
||||
|
@ -251,7 +249,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
const val APP_INTRO_REQUEST = 2323
|
||||
const val HOME = 0
|
||||
|
|
|
@ -19,6 +19,7 @@ import code.name.monkey.retromusic.fragments.NowPlayingScreen.ADAPTIVE
|
|||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.BLUR
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.BLUR_CARD
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.CARD
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.CIRCLE
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.COLOR
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.FIT
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.FLAT
|
||||
|
@ -34,6 +35,7 @@ import code.name.monkey.retromusic.fragments.player.adaptive.AdaptiveFragment
|
|||
import code.name.monkey.retromusic.fragments.player.blur.BlurPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.card.CardFragment
|
||||
import code.name.monkey.retromusic.fragments.player.cardblur.CardBlurFragment
|
||||
import code.name.monkey.retromusic.fragments.player.circle.CirclePlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.color.ColorFragment
|
||||
import code.name.monkey.retromusic.fragments.player.fit.FitFragment
|
||||
import code.name.monkey.retromusic.fragments.player.flat.FlatPlayerFragment
|
||||
|
@ -249,6 +251,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
|
|||
COLOR -> ColorFragment()
|
||||
TINY -> TinyPlayerFragment()
|
||||
PEAK -> PeakPlayerFragment()
|
||||
CIRCLE -> CirclePlayerFragment()
|
||||
else -> PlayerFragment()
|
||||
} // must implement AbsPlayerFragment
|
||||
supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment)
|
||||
|
|
|
@ -18,6 +18,7 @@ enum class NowPlayingScreen constructor(
|
|||
PEAK(R.string.peak, R.drawable.np_peak, 14),
|
||||
|
||||
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
|
||||
CIRCLE(R.string.circle, R.drawable.np_adaptive, 15),
|
||||
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
||||
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
||||
CARD(R.string.card, R.drawable.np_card, 6),
|
||||
|
|
|
@ -18,21 +18,31 @@ import code.name.monkey.appthemehelper.util.ATHUtil
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
|
||||
import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
|
||||
import code.name.monkey.retromusic.dialogs.*
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
|
||||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
|
||||
import code.name.monkey.retromusic.dialogs.SleepTimerDialog
|
||||
import code.name.monkey.retromusic.dialogs.SongDetailDialog
|
||||
import code.name.monkey.retromusic.dialogs.SongShareDialog
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.PaletteColorHolder
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.model.lyrics.Lyrics
|
||||
import code.name.monkey.retromusic.util.*
|
||||
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
|
||||
import code.name.monkey.retromusic.util.LyricUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import code.name.monkey.retromusic.util.RingtoneManager
|
||||
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.statusBarShadow
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
||||
Toolbar.OnMenuItemClickListener,
|
||||
PaletteColorHolder,
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
Toolbar.OnMenuItemClickListener,
|
||||
PaletteColorHolder,
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
var callbacks: Callbacks? = null
|
||||
private set
|
||||
|
@ -41,7 +51,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null
|
||||
|
||||
override fun onAttach(
|
||||
context: Context
|
||||
context: Context
|
||||
) {
|
||||
super.onAttach(context)
|
||||
try {
|
||||
|
@ -57,7 +67,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
}
|
||||
|
||||
override fun onMenuItemClick(
|
||||
item: MenuItem
|
||||
item: MenuItem
|
||||
): Boolean {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
when (item.itemId) {
|
||||
|
@ -83,7 +93,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
}
|
||||
R.id.action_save_playing_queue -> {
|
||||
CreatePlaylistDialog.create(MusicPlayerRemote.playingQueue)
|
||||
.show(requireFragmentManager(), "ADD_TO_PLAYLIST")
|
||||
.show(requireFragmentManager(), "ADD_TO_PLAYLIST")
|
||||
return true
|
||||
}
|
||||
R.id.action_tag_editor -> {
|
||||
|
@ -130,7 +140,8 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
}
|
||||
R.id.action_go_to_genre -> {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
val trackUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, song.id.toLong())
|
||||
val trackUri =
|
||||
ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, song.id.toLong())
|
||||
retriever.setDataSource(activity, trackUri)
|
||||
var genre: String? = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)
|
||||
if (genre == null) {
|
||||
|
@ -147,7 +158,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
MusicUtil.toggleFavorite(requireActivity(), song)
|
||||
}
|
||||
|
||||
abstract fun playerToolbar(): Toolbar
|
||||
abstract fun playerToolbar(): Toolbar?
|
||||
|
||||
abstract fun onShow()
|
||||
|
||||
|
@ -194,9 +205,9 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
R.drawable.ic_favorite_border_white_24dp
|
||||
|
||||
val drawable = RetroUtil.getTintedVectorDrawable(requireContext(), res, toolbarIconColor())
|
||||
if (playerToolbar().menu.findItem(R.id.action_toggle_favorite) != null)
|
||||
playerToolbar().menu.findItem(R.id.action_toggle_favorite).setIcon(drawable).title = if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(R.string.action_add_to_favorites)
|
||||
|
||||
if (playerToolbar() != null && playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite) != null)
|
||||
playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite).setIcon(drawable).title =
|
||||
if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(R.string.action_add_to_favorites)
|
||||
}
|
||||
}.execute(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
|
@ -238,17 +249,18 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
}
|
||||
|
||||
open fun setLyrics(l: Lyrics?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
view.setBackgroundColor(ATHUtil.resolveColor(requireContext(), R.attr.colorSecondary))
|
||||
if (PreferenceUtil.getInstance(requireContext()).fullScreenMode &&
|
||||
view.findViewById<View>(R.id.status_bar) != null) {
|
||||
view.findViewById<View>(R.id.status_bar) != null
|
||||
) {
|
||||
view.findViewById<View>(R.id.status_bar).visibility = View.GONE
|
||||
}
|
||||
playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?
|
||||
playerAlbumCoverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?
|
||||
playerAlbumCoverFragment?.setCallbacks(this)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
|
@ -269,8 +281,8 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
|
||||
|
||||
return MusicUtil.buildInfoString(
|
||||
resources.getString(R.string.up_next),
|
||||
MusicUtil.getReadableDurationString(duration)
|
||||
resources.getString(R.string.up_next),
|
||||
MusicUtil.getReadableDurationString(duration)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.fragments.player.circle
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2020-01-06.
|
||||
*/
|
||||
|
||||
class CirclePlayerFragment : AbsPlayerFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_circle_player, container, false)
|
||||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onShow() {
|
||||
}
|
||||
|
||||
override fun onHide() {
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean = false
|
||||
|
||||
override fun toolbarIconColor(): Int = Color.RED
|
||||
|
||||
override val paletteColor: Int
|
||||
get() = Color.BLACK
|
||||
|
||||
override fun onColorChanged(color: Int) {
|
||||
}
|
||||
|
||||
override fun onFavoriteToggled() {
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package code.name.monkey.retromusic.fragments.player.full
|
||||
|
||||
import android.app.ActivityOptions
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -155,7 +156,15 @@ class FullPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
|
|||
|
||||
private fun setupArtist() {
|
||||
artistImage.setOnClickListener {
|
||||
NavigationUtil.goToArtist(requireActivity(), MusicPlayerRemote.currentSong.artistId)
|
||||
val transitionName =
|
||||
"${getString(R.string.transition_artist_image)}_${MusicPlayerRemote.currentSong.artistId}"
|
||||
val activityOptions =
|
||||
ActivityOptions.makeSceneTransitionAnimation(requireActivity(), artistImage, transitionName)
|
||||
NavigationUtil.goToArtistOptions(
|
||||
requireActivity(),
|
||||
MusicPlayerRemote.currentSong.artistId,
|
||||
activityOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import android.content.Intent;
|
|||
import android.media.audiofx.AudioEffect;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.activities.AboutActivity;
|
||||
|
@ -79,7 +78,7 @@ public class NavigationUtil {
|
|||
ActivityCompat.startActivity(activity, intent, null);
|
||||
}
|
||||
|
||||
public static void goToArtistOptions(@NotNull AppCompatActivity activity,
|
||||
public static void goToArtistOptions(@NotNull Activity activity,
|
||||
int artistId,
|
||||
@NonNull ActivityOptions options) {
|
||||
|
||||
|
|
577
app/src/main/java/code/name/monkey/retromusic/views/SeekArc.java
Normal file
577
app/src/main/java/code/name/monkey/retromusic/views/SeekArc.java
Normal file
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
package code.name.monkey.retromusic.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
* SeekArc.java
|
||||
*
|
||||
* This is a class that functions much like a SeekBar but
|
||||
* follows a circle path instead of a straight line.
|
||||
*
|
||||
* @author Neil Davies
|
||||
*/
|
||||
public class SeekArc extends View {
|
||||
|
||||
public interface OnSeekArcChangeListener {
|
||||
|
||||
/**
|
||||
* Notification that the progress level has changed. Clients can use the
|
||||
* fromUser parameter to distinguish user-initiated changes from those
|
||||
* that occurred programmatically.
|
||||
*
|
||||
* @param seekArc The SeekArc whose progress has changed
|
||||
* @param progress The current progress level. This will be in the range
|
||||
* 0..max where max was set by
|
||||
* {@link ProgressArc#setMax(int)}. (The default value for
|
||||
* max is 100.)
|
||||
* @param fromUser True if the progress change was initiated by the user.
|
||||
*/
|
||||
void onProgressChanged(SeekArc seekArc, int progress, boolean fromUser);
|
||||
|
||||
/**
|
||||
* Notification that the user has started a touch gesture. Clients may
|
||||
* want to use this to disable advancing the seekbar.
|
||||
*
|
||||
* @param seekArc The SeekArc in which the touch gesture began
|
||||
*/
|
||||
void onStartTrackingTouch(SeekArc seekArc);
|
||||
|
||||
/**
|
||||
* Notification that the user has finished a touch gesture. Clients may
|
||||
* want to use this to re-enable advancing the seekarc.
|
||||
*
|
||||
* @param seekArc The SeekArc in which the touch gesture began
|
||||
*/
|
||||
void onStopTrackingTouch(SeekArc seekArc);
|
||||
}
|
||||
|
||||
private static final String TAG = SeekArc.class.getSimpleName();
|
||||
|
||||
private static int INVALID_PROGRESS_VALUE = -1;
|
||||
|
||||
// The initial rotational offset -90 means we start at 12 o'clock
|
||||
private final int mAngleOffset = -90;
|
||||
|
||||
private Paint mArcPaint;
|
||||
|
||||
// Internal variables
|
||||
private int mArcRadius = 0;
|
||||
|
||||
private RectF mArcRect = new RectF();
|
||||
|
||||
/**
|
||||
* The Width of the background arc for the SeekArc
|
||||
*/
|
||||
private int mArcWidth = 2;
|
||||
|
||||
/**
|
||||
* Will the progress increase clockwise or anti-clockwise
|
||||
*/
|
||||
private boolean mClockwise = true;
|
||||
|
||||
/**
|
||||
* is the control enabled/touchable
|
||||
*/
|
||||
private boolean mEnabled = true;
|
||||
|
||||
/**
|
||||
* The Maximum value that this SeekArc can be set to
|
||||
*/
|
||||
private int mMax = 100;
|
||||
|
||||
private OnSeekArcChangeListener mOnSeekArcChangeListener;
|
||||
|
||||
/**
|
||||
* The Current value that the SeekArc is set to
|
||||
*/
|
||||
private int mProgress = 0;
|
||||
|
||||
private Paint mProgressPaint;
|
||||
|
||||
private float mProgressSweep = 0;
|
||||
|
||||
/**
|
||||
* The width of the progress line for this SeekArc
|
||||
*/
|
||||
private int mProgressWidth = 4;
|
||||
|
||||
/**
|
||||
* The rotation of the SeekArc- 0 is twelve o'clock
|
||||
*/
|
||||
private int mRotation = 0;
|
||||
|
||||
/**
|
||||
* Give the SeekArc rounded edges
|
||||
*/
|
||||
private boolean mRoundedEdges = false;
|
||||
|
||||
/**
|
||||
* The Angle to start drawing this Arc from
|
||||
*/
|
||||
private int mStartAngle = 0;
|
||||
|
||||
/**
|
||||
* The Angle through which to draw the arc (Max is 360)
|
||||
*/
|
||||
private int mSweepAngle = 360;
|
||||
|
||||
/**
|
||||
* The Drawable for the seek arc thumbnail
|
||||
*/
|
||||
private Drawable mThumb;
|
||||
|
||||
private int mThumbXPos;
|
||||
|
||||
private int mThumbYPos;
|
||||
|
||||
private double mTouchAngle;
|
||||
|
||||
private float mTouchIgnoreRadius;
|
||||
|
||||
/**
|
||||
* Enable touch inside the SeekArc
|
||||
*/
|
||||
private boolean mTouchInside = true;
|
||||
|
||||
private int mTranslateX;
|
||||
|
||||
private int mTranslateY;
|
||||
|
||||
public SeekArc(Context context) {
|
||||
super(context);
|
||||
init(context, null, 0);
|
||||
}
|
||||
|
||||
public SeekArc(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs, R.attr.seekArcStyle);
|
||||
}
|
||||
|
||||
public SeekArc(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public int getArcColor() {
|
||||
return mArcPaint.getColor();
|
||||
}
|
||||
|
||||
public void setArcColor(int color) {
|
||||
mArcPaint.setColor(color);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public int getArcRotation() {
|
||||
return mRotation;
|
||||
}
|
||||
|
||||
public void setArcRotation(int mRotation) {
|
||||
this.mRotation = mRotation;
|
||||
updateThumbPosition();
|
||||
}
|
||||
|
||||
public int getArcWidth() {
|
||||
return mArcWidth;
|
||||
}
|
||||
|
||||
public void setArcWidth(int mArcWidth) {
|
||||
this.mArcWidth = mArcWidth;
|
||||
mArcPaint.setStrokeWidth(mArcWidth);
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return mMax;
|
||||
}
|
||||
|
||||
public void setMax(int mMax) {
|
||||
this.mMax = mMax;
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return mProgress;
|
||||
}
|
||||
|
||||
public void setProgress(int progress) {
|
||||
updateProgress(progress, false);
|
||||
}
|
||||
|
||||
public int getProgressColor() {
|
||||
return mProgressPaint.getColor();
|
||||
}
|
||||
|
||||
public void setProgressColor(int color) {
|
||||
mProgressPaint.setColor(color);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public int getProgressWidth() {
|
||||
return mProgressWidth;
|
||||
}
|
||||
|
||||
public void setProgressWidth(int mProgressWidth) {
|
||||
this.mProgressWidth = mProgressWidth;
|
||||
mProgressPaint.setStrokeWidth(mProgressWidth);
|
||||
}
|
||||
|
||||
public int getStartAngle() {
|
||||
return mStartAngle;
|
||||
}
|
||||
|
||||
public void setStartAngle(int mStartAngle) {
|
||||
this.mStartAngle = mStartAngle;
|
||||
updateThumbPosition();
|
||||
}
|
||||
|
||||
public int getSweepAngle() {
|
||||
return mSweepAngle;
|
||||
}
|
||||
|
||||
public void setSweepAngle(int mSweepAngle) {
|
||||
this.mSweepAngle = mSweepAngle;
|
||||
updateThumbPosition();
|
||||
}
|
||||
|
||||
public boolean isClockwise() {
|
||||
return mClockwise;
|
||||
}
|
||||
|
||||
public void setClockwise(boolean isClockwise) {
|
||||
mClockwise = isClockwise;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.mEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mEnabled) {
|
||||
this.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
onStartTrackingTouch();
|
||||
updateOnTouch(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
updateOnTouch(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
onStopTrackingTouch();
|
||||
setPressed(false);
|
||||
this.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
onStopTrackingTouch();
|
||||
setPressed(false);
|
||||
this.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a listener to receive notifications of changes to the SeekArc's
|
||||
* progress level. Also provides notifications of when the user starts and
|
||||
* stops a touch gesture within the SeekArc.
|
||||
*
|
||||
* @param l The seek bar notification listener
|
||||
* @see SeekArc.OnSeekBarChangeListener
|
||||
*/
|
||||
public void setOnSeekArcChangeListener(OnSeekArcChangeListener l) {
|
||||
mOnSeekArcChangeListener = l;
|
||||
}
|
||||
|
||||
public void setRoundedEdges(boolean isEnabled) {
|
||||
mRoundedEdges = isEnabled;
|
||||
if (mRoundedEdges) {
|
||||
mArcPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
} else {
|
||||
mArcPaint.setStrokeCap(Paint.Cap.SQUARE);
|
||||
mProgressPaint.setStrokeCap(Paint.Cap.SQUARE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTouchInSide(boolean isEnabled) {
|
||||
int thumbHalfheight = (int) mThumb.getIntrinsicHeight() / 2;
|
||||
int thumbHalfWidth = (int) mThumb.getIntrinsicWidth() / 2;
|
||||
mTouchInside = isEnabled;
|
||||
if (mTouchInside) {
|
||||
mTouchIgnoreRadius = (float) mArcRadius / 4;
|
||||
} else {
|
||||
// Don't use the exact radius makes interaction too tricky
|
||||
mTouchIgnoreRadius = mArcRadius
|
||||
- Math.min(thumbHalfWidth, thumbHalfheight);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
if (mThumb != null && mThumb.isStateful()) {
|
||||
int[] state = getDrawableState();
|
||||
mThumb.setState(state);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (!mClockwise) {
|
||||
canvas.scale(-1, 1, mArcRect.centerX(), mArcRect.centerY());
|
||||
}
|
||||
|
||||
// Draw the arcs
|
||||
final int arcStart = mStartAngle + mAngleOffset + mRotation;
|
||||
final int arcSweep = mSweepAngle;
|
||||
canvas.drawArc(mArcRect, arcStart, arcSweep, false, mArcPaint);
|
||||
canvas.drawArc(mArcRect, arcStart, mProgressSweep, false,
|
||||
mProgressPaint);
|
||||
|
||||
if (mEnabled) {
|
||||
// Draw the thumb nail
|
||||
canvas.translate(mTranslateX - mThumbXPos, mTranslateY - mThumbYPos);
|
||||
mThumb.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
|
||||
final int height = getDefaultSize(getSuggestedMinimumHeight(),
|
||||
heightMeasureSpec);
|
||||
final int width = getDefaultSize(getSuggestedMinimumWidth(),
|
||||
widthMeasureSpec);
|
||||
final int min = Math.min(width, height);
|
||||
float top = 0;
|
||||
float left = 0;
|
||||
int arcDiameter = 0;
|
||||
|
||||
mTranslateX = (int) (width * 0.5f);
|
||||
mTranslateY = (int) (height * 0.5f);
|
||||
|
||||
arcDiameter = min - getPaddingLeft();
|
||||
mArcRadius = arcDiameter / 2;
|
||||
top = height / 2 - (arcDiameter / 2);
|
||||
left = width / 2 - (arcDiameter / 2);
|
||||
mArcRect.set(left, top, left + arcDiameter, top + arcDiameter);
|
||||
|
||||
int arcStart = (int) mProgressSweep + mStartAngle + mRotation + 90;
|
||||
mThumbXPos = (int) (mArcRadius * Math.cos(Math.toRadians(arcStart)));
|
||||
mThumbYPos = (int) (mArcRadius * Math.sin(Math.toRadians(arcStart)));
|
||||
|
||||
setTouchInSide(mTouchInside);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private int getProgressForAngle(double angle) {
|
||||
int touchProgress = (int) Math.round(valuePerDegree() * angle);
|
||||
|
||||
touchProgress = (touchProgress < 0) ? INVALID_PROGRESS_VALUE
|
||||
: touchProgress;
|
||||
touchProgress = (touchProgress > mMax) ? INVALID_PROGRESS_VALUE
|
||||
: touchProgress;
|
||||
return touchProgress;
|
||||
}
|
||||
|
||||
private double getTouchDegrees(float xPos, float yPos) {
|
||||
float x = xPos - mTranslateX;
|
||||
float y = yPos - mTranslateY;
|
||||
//invert the x-coord if we are rotating anti-clockwise
|
||||
x = (mClockwise) ? x : -x;
|
||||
// convert to arc Angle
|
||||
double angle = Math.toDegrees(Math.atan2(y, x) + (Math.PI / 2)
|
||||
- Math.toRadians(mRotation));
|
||||
if (angle < 0) {
|
||||
angle = 360 + angle;
|
||||
}
|
||||
angle -= mStartAngle;
|
||||
return angle;
|
||||
}
|
||||
|
||||
private boolean ignoreTouch(float xPos, float yPos) {
|
||||
boolean ignore = false;
|
||||
float x = xPos - mTranslateX;
|
||||
float y = yPos - mTranslateY;
|
||||
|
||||
float touchRadius = (float) Math.sqrt(((x * x) + (y * y)));
|
||||
if (touchRadius < mTouchIgnoreRadius) {
|
||||
ignore = true;
|
||||
}
|
||||
return ignore;
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs, int defStyle) {
|
||||
|
||||
Log.d(TAG, "Initialising SeekArc");
|
||||
final Resources res = getResources();
|
||||
float density = context.getResources().getDisplayMetrics().density;
|
||||
|
||||
// Defaults, may need to link this into theme settings
|
||||
int arcColor = res.getColor(R.color.progress_gray);
|
||||
int progressColor = res.getColor(R.color.default_blue_light);
|
||||
int thumbHalfheight = 0;
|
||||
int thumbHalfWidth = 0;
|
||||
mThumb = res.getDrawable(R.drawable.switch_thumb_material);
|
||||
// Convert progress width to pixels for current density
|
||||
mProgressWidth = (int) (mProgressWidth * density);
|
||||
|
||||
if (attrs != null) {
|
||||
// Attribute initialization
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.SeekArc, defStyle, 0);
|
||||
|
||||
Drawable thumb = a.getDrawable(R.styleable.SeekArc_thumb);
|
||||
if (thumb != null) {
|
||||
mThumb = thumb;
|
||||
}
|
||||
|
||||
thumbHalfheight = (int) mThumb.getIntrinsicHeight() / 2;
|
||||
thumbHalfWidth = (int) mThumb.getIntrinsicWidth() / 2;
|
||||
mThumb.setBounds(-thumbHalfWidth, -thumbHalfheight, thumbHalfWidth,
|
||||
thumbHalfheight);
|
||||
|
||||
mMax = a.getInteger(R.styleable.SeekArc_max, mMax);
|
||||
mProgress = a.getInteger(R.styleable.SeekArc_progress, mProgress);
|
||||
mProgressWidth = (int) a.getDimension(
|
||||
R.styleable.SeekArc_progressWidth, mProgressWidth);
|
||||
mArcWidth = (int) a.getDimension(R.styleable.SeekArc_arcWidth,
|
||||
mArcWidth);
|
||||
mStartAngle = a.getInt(R.styleable.SeekArc_startAngle, mStartAngle);
|
||||
mSweepAngle = a.getInt(R.styleable.SeekArc_sweepAngle, mSweepAngle);
|
||||
mRotation = a.getInt(R.styleable.SeekArc_rotation, mRotation);
|
||||
mRoundedEdges = a.getBoolean(R.styleable.SeekArc_roundEdges,
|
||||
mRoundedEdges);
|
||||
mTouchInside = a.getBoolean(R.styleable.SeekArc_touchInside,
|
||||
mTouchInside);
|
||||
mClockwise = a.getBoolean(R.styleable.SeekArc_clockwise,
|
||||
mClockwise);
|
||||
mEnabled = a.getBoolean(R.styleable.SeekArc_enabled, mEnabled);
|
||||
|
||||
arcColor = a.getColor(R.styleable.SeekArc_arcColor, arcColor);
|
||||
progressColor = a.getColor(R.styleable.SeekArc_progressColor,
|
||||
progressColor);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
mProgress = (mProgress > mMax) ? mMax : mProgress;
|
||||
mProgress = (mProgress < 0) ? 0 : mProgress;
|
||||
|
||||
mSweepAngle = (mSweepAngle > 360) ? 360 : mSweepAngle;
|
||||
mSweepAngle = (mSweepAngle < 0) ? 0 : mSweepAngle;
|
||||
|
||||
mProgressSweep = (float) mProgress / mMax * mSweepAngle;
|
||||
|
||||
mStartAngle = (mStartAngle > 360) ? 0 : mStartAngle;
|
||||
mStartAngle = (mStartAngle < 0) ? 0 : mStartAngle;
|
||||
|
||||
mArcPaint = new Paint();
|
||||
mArcPaint.setColor(arcColor);
|
||||
mArcPaint.setAntiAlias(true);
|
||||
mArcPaint.setStyle(Paint.Style.STROKE);
|
||||
mArcPaint.setStrokeWidth(mArcWidth);
|
||||
//mArcPaint.setAlpha(45);
|
||||
|
||||
mProgressPaint = new Paint();
|
||||
mProgressPaint.setColor(progressColor);
|
||||
mProgressPaint.setAntiAlias(true);
|
||||
mProgressPaint.setStyle(Paint.Style.STROKE);
|
||||
mProgressPaint.setStrokeWidth(mProgressWidth);
|
||||
|
||||
if (mRoundedEdges) {
|
||||
mArcPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
}
|
||||
}
|
||||
|
||||
private void onProgressRefresh(int progress, boolean fromUser) {
|
||||
updateProgress(progress, fromUser);
|
||||
}
|
||||
|
||||
private void onStartTrackingTouch() {
|
||||
if (mOnSeekArcChangeListener != null) {
|
||||
mOnSeekArcChangeListener.onStartTrackingTouch(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void onStopTrackingTouch() {
|
||||
if (mOnSeekArcChangeListener != null) {
|
||||
mOnSeekArcChangeListener.onStopTrackingTouch(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOnTouch(MotionEvent event) {
|
||||
boolean ignoreTouch = ignoreTouch(event.getX(), event.getY());
|
||||
if (ignoreTouch) {
|
||||
return;
|
||||
}
|
||||
setPressed(true);
|
||||
mTouchAngle = getTouchDegrees(event.getX(), event.getY());
|
||||
int progress = getProgressForAngle(mTouchAngle);
|
||||
onProgressRefresh(progress, true);
|
||||
}
|
||||
|
||||
private void updateProgress(int progress, boolean fromUser) {
|
||||
|
||||
if (progress == INVALID_PROGRESS_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
progress = (progress > mMax) ? mMax : progress;
|
||||
progress = (progress < 0) ? 0 : progress;
|
||||
mProgress = progress;
|
||||
|
||||
if (mOnSeekArcChangeListener != null) {
|
||||
mOnSeekArcChangeListener
|
||||
.onProgressChanged(this, progress, fromUser);
|
||||
}
|
||||
|
||||
mProgressSweep = (float) progress / mMax * mSweepAngle;
|
||||
|
||||
updateThumbPosition();
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void updateThumbPosition() {
|
||||
int thumbAngle = (int) (mStartAngle + mProgressSweep + mRotation + 90);
|
||||
mThumbXPos = (int) (mArcRadius * Math.cos(Math.toRadians(thumbAngle)));
|
||||
mThumbYPos = (int) (mArcRadius * Math.sin(Math.toRadians(thumbAngle)));
|
||||
}
|
||||
|
||||
private float valuePerDegree() {
|
||||
return (float) mMax / mSweepAngle;
|
||||
}
|
||||
}
|
119
app/src/main/res/layout/fragment_circle_player.xml
Normal file
119
app/src/main/res/layout/fragment_circle_player.xml
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2020 Hemanth Savarala.
|
||||
~
|
||||
~ Licensed under the GNU General Public License v3
|
||||
~
|
||||
~ This is free software: you can redistribute it and/or modify it under
|
||||
~ the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
~
|
||||
~ This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
~ See the GNU General Public License for more details.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/titleContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextViewHeadline5"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:padding="16dp"
|
||||
android:textAppearance="@style/TextViewBody1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleContainer"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<code.name.monkey.retromusic.views.SeekArc
|
||||
android:id="@+id/progressSlider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="280dp"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text"
|
||||
app:rotation="180"
|
||||
app:startAngle="30"
|
||||
app:sweepAngle="300"
|
||||
app:touchInside="true" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/playPauseButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/progressSlider"
|
||||
app:layout_constraintEnd_toEndOf="@+id/progressSlider"
|
||||
app:layout_constraintStart_toStartOf="@+id/progressSlider"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/nextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
|
||||
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
|
||||
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
|
||||
app:srcCompat="@drawable/ic_skip_next_round_white_32dp"
|
||||
app:tint="@color/md_green_500" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/previousButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
|
||||
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
|
||||
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
|
||||
app:srcCompat="@drawable/ic_skip_previous_round_white_32dp"
|
||||
app:tint="@color/md_green_500" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/volumeText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Volume"
|
||||
app:layout_constraintBottom_toTopOf="@+id/volume"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/volume" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/volume"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/progressSlider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/progressSlider"
|
||||
tools:text="00:00" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -42,6 +42,8 @@
|
|||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:freezesText="true"
|
||||
android:gravity="center"
|
||||
android:paddingTop="8dp"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
|
@ -55,6 +57,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:paddingTop="8dp"
|
||||
tools:text="Text" />
|
||||
|
|
|
@ -34,4 +34,8 @@
|
|||
<color name="card_shadow_1">#d4d4d4</color>
|
||||
<color name="card_shadow_2">#dddddd</color>
|
||||
<color name="card_detailing">#eee</color>
|
||||
|
||||
<color name="progress_gray">#FFD8D8D8</color>
|
||||
<color name="progress_gray_dark">#FF383838</color>
|
||||
<color name="default_blue_light">#ff33b5e5</color>
|
||||
</resources>
|
||||
|
|
48
app/src/main/res/values/seekarc_attrs.xml
Normal file
48
app/src/main/res/values/seekarc_attrs.xml
Normal file
|
@ -0,0 +1,48 @@
|
|||
<!--
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Triggertrap Ltd
|
||||
Author Neil Davies
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<declare-styleable name="SeekArc">
|
||||
<attr name="thumb" format="reference" />
|
||||
<attr name="thumbOffset" format="dimension" />
|
||||
<attr name="max" format="integer" />
|
||||
<attr name="progressWidth" format="dimension" />
|
||||
<attr name="arcWidth" format="dimension" />
|
||||
<attr name="progress" format="integer" />
|
||||
<attr name="rotation" format="integer" />
|
||||
<attr name="startAngle" format="integer" />
|
||||
<attr name="sweepAngle" format="integer" />
|
||||
<attr name="arcColor" format="color" />
|
||||
<attr name="progressColor" format="color" />
|
||||
<attr name="roundEdges" format="boolean" />
|
||||
<attr name="touchInside" format="boolean" />
|
||||
<attr name="clockwise" format="boolean" />
|
||||
<attr name="enabled" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="SeekArcTheme">
|
||||
<attr name="seekArcStyle" format="reference"></attr>
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
|
@ -817,4 +817,5 @@
|
|||
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
|
||||
|
||||
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
|
||||
<string name="circle">Circle</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue