From 23d920c759303602c2a6cde38983b2aa4dbb82c2 Mon Sep 17 00:00:00 2001 From: lado Date: Tue, 9 Jun 2015 14:07:14 +0200 Subject: StudioStructur --- .../java/de/androvdr/widget/AnimatedTextView.java | 101 ++++++ .../main/java/de/androvdr/widget/FontAwesome.java | 25 ++ .../java/de/androvdr/widget/FontAwesomeButton.java | 36 ++ .../src/main/java/de/androvdr/widget/LruCache.java | 396 +++++++++++++++++++++ .../main/java/de/androvdr/widget/SquareButton.java | 35 ++ 5 files changed, 593 insertions(+) create mode 100644 vdrmanager/app/src/main/java/de/androvdr/widget/AnimatedTextView.java create mode 100644 vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesome.java create mode 100644 vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesomeButton.java create mode 100644 vdrmanager/app/src/main/java/de/androvdr/widget/LruCache.java create mode 100644 vdrmanager/app/src/main/java/de/androvdr/widget/SquareButton.java (limited to 'vdrmanager/app/src/main/java/de/androvdr') diff --git a/vdrmanager/app/src/main/java/de/androvdr/widget/AnimatedTextView.java b/vdrmanager/app/src/main/java/de/androvdr/widget/AnimatedTextView.java new file mode 100644 index 0000000..b6c120b --- /dev/null +++ b/vdrmanager/app/src/main/java/de/androvdr/widget/AnimatedTextView.java @@ -0,0 +1,101 @@ +package de.androvdr.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.TextView; + +/** + * Created by lado on 04.05.15. + */ +public class AnimatedTextView extends TextView { + private static final int IS_ANIMATING_TAG_ID = "isAnimating".hashCode(); + + private Animation fadeInAnimation; + private Animation fadeOutAnimation; + + public AnimatedTextView(Context context) { + super(context); + + initAnimations(context); + } + + public AnimatedTextView(Context context, AttributeSet attrs) { + super(context, attrs); + + initAnimations(context); + } + + public AnimatedTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + initAnimations(context); + } + + public void initAnimations(Context context) { + fadeInAnimation = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_in); + + fadeOutAnimation = new AlphaAnimation(1.0f, 0.0f); + fadeOutAnimation.setDuration(100); + fadeInAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + setAnimatingFlag(true); + } + + @Override + public void onAnimationEnd(Animation animation) { + setAnimatingFlag(false); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + + fadeOutAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + setAnimatingFlag(false); + } + + @Override + public void onAnimationEnd(Animation animation) { + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + + }); + + setAnimatingFlag(false); + } + + public void fadeOut() { + if (getVisibility() == View.VISIBLE) { + startAnimation(fadeOutAnimation); + setVisibility(View.INVISIBLE); + } + } + + public void fadeIn() { + //if (getVisibility() == View.INVISIBLE && !isAnimating()) { +// startAnimation(fadeInAnimation); + setVisibility(View.VISIBLE); + // } + } + + private boolean isAnimating() { + return (Boolean) getTag(IS_ANIMATING_TAG_ID) == true; + } + + private void setAnimatingFlag(boolean isAnimating) { + setTag(IS_ANIMATING_TAG_ID, new Boolean(isAnimating)); + } +} diff --git a/vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesome.java b/vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesome.java new file mode 100644 index 0000000..77d7c07 --- /dev/null +++ b/vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesome.java @@ -0,0 +1,25 @@ +package de.androvdr.widget; + +import android.content.Context; +import android.graphics.Typeface; + +/** + * Created by lado on 04.05.15. + */ +public class FontAwesome { + + private static Typeface mFont; + + + public static Typeface getFontAwesome(Context context){ + + if(mFont != null){ + return mFont; + } + + mFont = Typeface.createFromAsset(context.getAssets(), "fonts/fontawesome-webfont.ttf"); + return mFont; + } + + +} diff --git a/vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesomeButton.java b/vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesomeButton.java new file mode 100644 index 0000000..22c4de1 --- /dev/null +++ b/vdrmanager/app/src/main/java/de/androvdr/widget/FontAwesomeButton.java @@ -0,0 +1,36 @@ +package de.androvdr.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.Button; + +/** + * Created by lado on 04.05.15. + */ +public class FontAwesomeButton extends Button { + + + public FontAwesomeButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initFontAwesome(); + + } + + public FontAwesomeButton(Context context, AttributeSet attrs) { + super(context, attrs); + initFontAwesome(); + + } + + public FontAwesomeButton(Context context) { + super(context); + initFontAwesome(); + } + + private void initFontAwesome(){ + if(isInEditMode() == false) { + setTypeface(FontAwesome.getFontAwesome(getContext().getApplicationContext().getApplicationContext())); + } + } + +} diff --git a/vdrmanager/app/src/main/java/de/androvdr/widget/LruCache.java b/vdrmanager/app/src/main/java/de/androvdr/widget/LruCache.java new file mode 100644 index 0000000..9186b15 --- /dev/null +++ b/vdrmanager/app/src/main/java/de/androvdr/widget/LruCache.java @@ -0,0 +1,396 @@ +package de.androvdr.widget; + +/** + * Created by lado on 04.05.15. + */ +/* + * 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 java.util.LinkedHashMap; + import java.util.Map; + +/** + * BEGIN LAYOUTLIB CHANGE + * This is a custom version that doesn't use the non standard LinkedHashMap#eldest. + * END LAYOUTLIB CHANGE + * + * A cache that holds strong references to a limited number of values. Each time + * a value is accessed, it is moved to the head of a queue. When a value is + * added to a full cache, the value at the end of that queue is evicted and may + * become eligible for garbage collection. + * + *

If your cached values hold resources that need to be explicitly released, + * override {@link #entryRemoved}. + * + *

If a cache miss should be computed on demand for the corresponding keys, + * override {@link #create}. This simplifies the calling code, allowing it to + * assume a value will always be returned, even when there's a cache miss. + * + *

By default, the cache size is measured in the number of entries. Override + * {@link #sizeOf} to size the cache in different units. For example, this cache + * is limited to 4MiB of bitmaps: + *

   {@code
+ *   int cacheSize = 4 * 1024 * 1024; // 4MiB
+ *   LruCache bitmapCache = new LruCache(cacheSize) {
+ *       protected int sizeOf(String key, Bitmap value) {
+ *           return value.getByteCount();
+ *       }
+ *   }}
+ * + *

This class is thread-safe. Perform multiple cache operations atomically by + * synchronizing on the cache:

   {@code
+ *   synchronized (cache) {
+ *     if (cache.get(key) == null) {
+ *         cache.put(key, value);
+ *     }
+ *   }}
+ * + *

This class does not allow null to be used as a key or value. A return + * value of null from {@link #get}, {@link #put} or {@link #remove} is + * unambiguous: the key was not in the cache. + * + *

This class appeared in Android 3.1 (Honeycomb MR1); it's available as part + * of Android's + * Support Package for earlier releases. + */ +public class LruCache { + private final LinkedHashMap map; + + /** Size of this cache in units. Not necessarily the number of elements. */ + private int size; + private int maxSize; + + private int putCount; + private int createCount; + private int evictionCount; + private int hitCount; + private int missCount; + + /** + * @param maxSize for caches that do not override {@link #sizeOf}, this is + * the maximum number of entries in the cache. For all other caches, + * this is the maximum sum of the sizes of the entries in this cache. + */ + public LruCache(int maxSize) { + if (maxSize <= 0) { + throw new IllegalArgumentException("maxSize <= 0"); + } + this.maxSize = maxSize; + this.map = new LinkedHashMap(0, 0.75f, true); + } + + /** + * Sets the size of the cache. + * @param maxSize The new maximum size. + * + * @hide + */ + public void resize(int maxSize) { + if (maxSize <= 0) { + throw new IllegalArgumentException("maxSize <= 0"); + } + + synchronized (this) { + this.maxSize = maxSize; + } + trimToSize(maxSize); + } + + /** + * Returns the value for {@code key} if it exists in the cache or can be + * created by {@code #create}. If a value was returned, it is moved to the + * head of the queue. This returns null if a value is not cached and cannot + * be created. + */ + public final V get(K key) { + if (key == null) { + throw new NullPointerException("key == null"); + } + + V mapValue; + synchronized (this) { + mapValue = map.get(key); + if (mapValue != null) { + hitCount++; + return mapValue; + } + missCount++; + } + + /* + * Attempt to create a value. This may take a long time, and the map + * may be different when create() returns. If a conflicting value was + * added to the map while create() was working, we leave that value in + * the map and release the created value. + */ + + V createdValue = create(key); + if (createdValue == null) { + return null; + } + + synchronized (this) { + createCount++; + mapValue = map.put(key, createdValue); + + if (mapValue != null) { + // There was a conflict so undo that last put + map.put(key, mapValue); + } else { + size += safeSizeOf(key, createdValue); + } + } + + if (mapValue != null) { + entryRemoved(false, key, createdValue, mapValue); + return mapValue; + } else { + trimToSize(maxSize); + return createdValue; + } + } + + /** + * Caches {@code value} for {@code key}. The value is moved to the head of + * the queue. + * + * @return the previous value mapped by {@code key}. + */ + public final V put(K key, V value) { + if (key == null || value == null) { + throw new NullPointerException("key == null || value == null"); + } + + V previous; + synchronized (this) { + putCount++; + size += safeSizeOf(key, value); + previous = map.put(key, value); + if (previous != null) { + size -= safeSizeOf(key, previous); + } + } + + if (previous != null) { + entryRemoved(false, key, previous, value); + } + + trimToSize(maxSize); + return previous; + } + + /** + * @param maxSize the maximum size of the cache before returning. May be -1 + * to evict even 0-sized elements. + */ + private void trimToSize(int maxSize) { + while (true) { + K key; + V value; + synchronized (this) { + if (size < 0 || (map.isEmpty() && size != 0)) { + throw new IllegalStateException(getClass().getName() + + ".sizeOf() is reporting inconsistent results!"); + } + + if (size <= maxSize) { + break; + } + + // BEGIN LAYOUTLIB CHANGE + // get the last item in the linked list. + // This is not efficient, the goal here is to minimize the changes + // compared to the platform version. + Map.Entry toEvict = null; + for (Map.Entry entry : map.entrySet()) { + toEvict = entry; + } + // END LAYOUTLIB CHANGE + + if (toEvict == null) { + break; + } + + key = toEvict.getKey(); + value = toEvict.getValue(); + map.remove(key); + size -= safeSizeOf(key, value); + evictionCount++; + } + + entryRemoved(true, key, value, null); + } + } + + /** + * Removes the entry for {@code key} if it exists. + * + * @return the previous value mapped by {@code key}. + */ + public final V remove(K key) { + if (key == null) { + throw new NullPointerException("key == null"); + } + + V previous; + synchronized (this) { + previous = map.remove(key); + if (previous != null) { + size -= safeSizeOf(key, previous); + } + } + + if (previous != null) { + entryRemoved(false, key, previous, null); + } + + return previous; + } + + /** + * Called for entries that have been evicted or removed. This method is + * invoked when a value is evicted to make space, removed by a call to + * {@link #remove}, or replaced by a call to {@link #put}. The default + * implementation does nothing. + * + *

The method is called without synchronization: other threads may + * access the cache while this method is executing. + * + * @param evicted true if the entry is being removed to make space, false + * if the removal was caused by a {@link #put} or {@link #remove}. + * @param newValue the new value for {@code key}, if it exists. If non-null, + * this removal was caused by a {@link #put}. Otherwise it was caused by + * an eviction or a {@link #remove}. + */ + protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {} + + /** + * Called after a cache miss to compute a value for the corresponding key. + * Returns the computed value or null if no value can be computed. The + * default implementation returns null. + * + *

The method is called without synchronization: other threads may + * access the cache while this method is executing. + * + *

If a value for {@code key} exists in the cache when this method + * returns, the created value will be released with {@link #entryRemoved} + * and discarded. This can occur when multiple threads request the same key + * at the same time (causing multiple values to be created), or when one + * thread calls {@link #put} while another is creating a value for the same + * key. + */ + protected V create(K key) { + return null; + } + + private int safeSizeOf(K key, V value) { + int result = sizeOf(key, value); + if (result < 0) { + throw new IllegalStateException("Negative size: " + key + "=" + value); + } + return result; + } + + /** + * Returns the size of the entry for {@code key} and {@code value} in + * user-defined units. The default implementation returns 1 so that size + * is the number of entries and max size is the maximum number of entries. + * + *

An entry's size must not change while it is in the cache. + */ + protected int sizeOf(K key, V value) { + return 1; + } + + /** + * Clear the cache, calling {@link #entryRemoved} on each removed entry. + */ + public final void evictAll() { + trimToSize(-1); // -1 will evict 0-sized elements + } + + /** + * For caches that do not override {@link #sizeOf}, this returns the number + * of entries in the cache. For all other caches, this returns the sum of + * the sizes of the entries in this cache. + */ + public synchronized final int size() { + return size; + } + + /** + * For caches that do not override {@link #sizeOf}, this returns the maximum + * number of entries in the cache. For all other caches, this returns the + * maximum sum of the sizes of the entries in this cache. + */ + public synchronized final int maxSize() { + return maxSize; + } + + /** + * Returns the number of times {@link #get} returned a value that was + * already present in the cache. + */ + public synchronized final int hitCount() { + return hitCount; + } + + /** + * Returns the number of times {@link #get} returned null or required a new + * value to be created. + */ + public synchronized final int missCount() { + return missCount; + } + + /** + * Returns the number of times {@link #create(Object)} returned a value. + */ + public synchronized final int createCount() { + return createCount; + } + + /** + * Returns the number of times {@link #put} was called. + */ + public synchronized final int putCount() { + return putCount; + } + + /** + * Returns the number of values that have been evicted. + */ + public synchronized final int evictionCount() { + return evictionCount; + } + + /** + * Returns a copy of the current contents of the cache, ordered from least + * recently accessed to most recently accessed. + */ + public synchronized final Map snapshot() { + return new LinkedHashMap(map); + } + + @Override public synchronized final String toString() { + int accesses = hitCount + missCount; + int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0; + return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]", + maxSize, hitCount, missCount, hitPercent); + } +} diff --git a/vdrmanager/app/src/main/java/de/androvdr/widget/SquareButton.java b/vdrmanager/app/src/main/java/de/androvdr/widget/SquareButton.java new file mode 100644 index 0000000..6c3ad29 --- /dev/null +++ b/vdrmanager/app/src/main/java/de/androvdr/widget/SquareButton.java @@ -0,0 +1,35 @@ +package de.androvdr.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.Button; + +public class SquareButton extends FontAwesomeButton { + + public SquareButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public SquareButton(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SquareButton(Context context) { + super(context); + } + + + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + + //Get canvas width and height + int w = MeasureSpec.getSize(widthMeasureSpec); + int h = MeasureSpec.getSize(heightMeasureSpec); + + w = Math.min(w, h); + h = w; + + setMeasuredDimension(w, h); + } +} \ No newline at end of file -- cgit v1.2.3