diff --git a/library-overlay/src/main/java/com/michaelflisar/lumberjack/OverlayLoggingSetup.java b/library-overlay/src/main/java/com/michaelflisar/lumberjack/OverlayLoggingSetup.java index ae78031..0c138bd 100644 --- a/library-overlay/src/main/java/com/michaelflisar/lumberjack/OverlayLoggingSetup.java +++ b/library-overlay/src/main/java/com/michaelflisar/lumberjack/OverlayLoggingSetup.java @@ -19,8 +19,7 @@ public class OverlayLoggingSetup private int mTextSizeInDp = 12; private int mOverlayHeightInDp = 150; private boolean mStartExpanded = true; - private int mLogPriorityForErrorFilter = Log.ERROR; - private boolean mStartWithShowErrorsOnly = false; + private int mDefaultMinVisibleLogPriority = Log.VERBOSE; private int mPermissionRequestCode = 200; private String mNotificationTitle = "Overlay logger"; @@ -165,26 +164,14 @@ public OverlayLoggingSetup withStartExpanded(boolean startExpanded) } /** - * only show logs of the defined level or higher in overlay logger if error filter is on - * DEFAULT: Log.ERRROR + * default value for miimimum visible log priority, by default all logs are visible + * DEFAULT: Log.VERBOSE * - * @param logPriority define the minimum log level that is visible in the overlay logger if error filter is on + * @param logPriority define the minimum log level that is visible in the overlay logger */ - public OverlayLoggingSetup withMinimumLogPriority(int logPriority) + public OverlayLoggingSetup withDefaultMinimumVisibleLogPriority(int logPriority) { - mLogPriorityForErrorFilter = logPriority; - return this; - } - - /** - * start the overlay logger with active error filter - * DEFAULT: false - * - * @param startWithShowErrorsOnly true to start the overlay logger with active error filter - */ - public OverlayLoggingSetup withStartWithShowErrorsOnly(boolean startWithShowErrorsOnly) - { - mStartWithShowErrorsOnly = startWithShowErrorsOnly; + mDefaultMinVisibleLogPriority = logPriority; return this; } @@ -247,14 +234,9 @@ public boolean getWithStartExpanded() return mStartExpanded; } - public int getLogPriorityForErrorFilter() - { - return mLogPriorityForErrorFilter; - } - - public boolean getStartWithShowErrorsOnly() + public int getDefaultMinVisibleLogPriority() { - return mStartWithShowErrorsOnly; + return mDefaultMinVisibleLogPriority; } public String getNotificationTitle() diff --git a/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/LogAdapter.java b/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/LogAdapter.java index e3e0561..75b35d8 100644 --- a/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/LogAdapter.java +++ b/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/LogAdapter.java @@ -20,38 +20,46 @@ public class LogAdapter extends RecyclerView.Adapter { - private boolean mIsFiltered; + private int mMinimumVisiblePriority; - private int mFilterLogLevel; private List mItems; private List mFilteredItems; - public LogAdapter(int filterLogLevel, boolean isFiltered) + public LogAdapter(int mimimumVisiblePriority) { - mFilterLogLevel = filterLogLevel; - mIsFiltered = isFiltered; + mMinimumVisiblePriority = mimimumVisiblePriority; mItems = new ArrayList<>(); mFilteredItems = new ArrayList<>(); } - public void setFiltered(boolean isFiltered) + public void setFiltered(int mimimumVisiblePriority) { - if (mIsFiltered != isFiltered) + if (mMinimumVisiblePriority != mimimumVisiblePriority) { - mIsFiltered = isFiltered; + mMinimumVisiblePriority = mimimumVisiblePriority; + calcFilteredItems(); notifyDataSetChanged(); } } + private void calcFilteredItems() + { + mFilteredItems.clear(); + for (OverlayLoggingTree.LogEntry item : mItems) + { + if (item.getPriority() >= mMinimumVisiblePriority) + mFilteredItems.add(item); + } + } + public boolean add(OverlayLoggingTree.LogEntry item) { mItems.add(item); - if (item.getPriority() >= mFilterLogLevel) + if (item.getPriority() >= mMinimumVisiblePriority) + { mFilteredItems.add(item); - if (mIsFiltered && item.getPriority() >= mFilterLogLevel) notifyItemInserted(mFilteredItems.size() - 1); - else if (!mIsFiltered) - notifyItemInserted(mItems.size() - 1); + } else return false; return true; @@ -67,7 +75,7 @@ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) @Override public void onBindViewHolder(ViewHolder holder, int position) { - OverlayLoggingTree.LogEntry item = mIsFiltered ? mFilteredItems.get(position) : mItems.get(position); + OverlayLoggingTree.LogEntry item = mFilteredItems.get(position); holder.text.setText(item.getMessage()); holder.text.setTextColor(item.getColor()); holder.text.setTextSize(TypedValue.COMPLEX_UNIT_DIP, item.getTextSizeInDp()); @@ -76,7 +84,7 @@ public void onBindViewHolder(ViewHolder holder, int position) @Override public int getItemCount() { - return mIsFiltered ? mFilteredItems.size() : mItems.size(); + return mFilteredItems.size(); } public static class ViewHolder extends RecyclerView.ViewHolder diff --git a/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayService.java b/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayService.java index 6dd9513..8dc1a80 100644 --- a/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayService.java +++ b/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayService.java @@ -50,12 +50,12 @@ public void run() { }; private boolean mPaused = false; - private boolean mErrorFilterActive; + private int mMinimumVisibleLogPriority; public void setSetup(OverlayLoggingSetup setup) { mSetup = setup; - mErrorFilterActive = mSetup.getStartWithShowErrorsOnly(); + mMinimumVisibleLogPriority = mSetup.getDefaultMinVisibleLogPriority(); } @Override @@ -120,23 +120,21 @@ private void createView() if (mView != null) return; - mView = new OverlayView(getApplicationContext(), mSetup, mErrorFilterActive); - mView.getCloseButton().setOnClickListener(new View.OnClickListener() + mView = new OverlayView(getApplicationContext(), mSetup, mMinimumVisibleLogPriority, new OverlayView.IFilterChangedListener() { @Override - public void onClick(View v) + public void onFilterChanged(int priority) { - destroyView(); - stopSelf(); + mMinimumVisibleLogPriority = priority; } }); - mView.getErrorButton().setOnClickListener(new View.OnClickListener() + mView.getCloseButton().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mErrorFilterActive = !mErrorFilterActive; - mView.updateErrorFilter(mErrorFilterActive); + destroyView(); + stopSelf(); } }); mView.getPauseButton().setOnClickListener(new View.OnClickListener() diff --git a/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayView.java b/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayView.java index f122fbf..9166fac 100644 --- a/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayView.java +++ b/library-overlay/src/main/java/com/michaelflisar/lumberjack/overlay/OverlayView.java @@ -1,7 +1,6 @@ package com.michaelflisar.lumberjack.overlay; import android.content.Context; -import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.support.v7.widget.LinearLayoutManager; @@ -23,6 +22,8 @@ import com.michaelflisar.lumberjack.OverlayLoggingSetup; import com.michaelflisar.lumberjack.OverlayLoggingTree; +import java.lang.reflect.Field; + /** * Created by flisar on 13.02.2017. */ @@ -33,7 +34,13 @@ class OverlayView extends FrameLayout private ImageView mCloseButton; private ImageView mCollapseExpandButton; private ImageView mPauseButton; - private ImageView mErrorButton; + private TextView mFilterButton; + private TextView mVerboseButton; + private TextView mDebugButton; + private TextView mInfoButton; + private TextView mWarnButton; + private TextView mErrorButton; + private LinearLayout mLLFilters; private TextView mLabel; private TextView mLabelErrors; private RecyclerView mRecyclerView; @@ -41,18 +48,18 @@ class OverlayView extends FrameLayout private int mErrors = 0; private LogAdapter mAdapter; private boolean mExpanded = true; - private int mMinimumLogPriority; - private boolean mShowErrorsOnly; - public OverlayView(Context context, OverlayLoggingSetup setup, boolean showErrorsOnly) + private IFilterChangedListener mFilterChangedListener; + + public OverlayView(Context context, OverlayLoggingSetup setup, int minimumVisibleLogPriority, IFilterChangedListener filterChangedListener) { super(context); + mFilterChangedListener = filterChangedListener; + mSetup = setup; mExpanded = mSetup.getWithStartExpanded(); - mMinimumLogPriority = mSetup.getLogPriorityForErrorFilter(); - mShowErrorsOnly = showErrorsOnly; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Point windowDimen = new Point(); @@ -62,33 +69,79 @@ public OverlayView(Context context, OverlayLoggingSetup setup, boolean showError int desiredLayoutHeight = dpToPx(context, setup.getOverlayHeight()); int layoutHeight = desiredLayoutHeight < windowDimen.y ? desiredLayoutHeight : windowDimen.y; - // Create layout - // TODO: Layout bottom/top unterscheiden: mSetup.getShowAtBottom() ? + // Create layout and get views View view = LayoutInflater.from(context).inflate(R.layout.overlay, null, false); - mCloseButton = (ImageView)view.findViewById(R.id.btClose); - mCollapseExpandButton = (ImageView)view.findViewById(R.id.btCollapseExpand); - mPauseButton = (ImageView)view.findViewById(R.id.btPause); - mErrorButton = (ImageView)view.findViewById(R.id.btErrors); + mRecyclerView = (RecyclerView)view.findViewById(R.id.rvLogs); + mLabel = (TextView)view.findViewById(R.id.tvLabel); + mLabelErrors = (TextView)view.findViewById(R.id.tvLabelError); + mCloseButton = (ImageView)view.findViewById(R.id.ivClose); + mCollapseExpandButton = (ImageView)view.findViewById(R.id.ivCollapseExpand); + mPauseButton = (ImageView)view.findViewById(R.id.ivPause); + mFilterButton = (TextView) view.findViewById(R.id.tvFilter); + mLLFilters = (LinearLayout)view.findViewById(R.id.llFilter); + mVerboseButton = (TextView) view.findViewById(R.id.tvVerbose); + mDebugButton = (TextView) view.findViewById(R.id.tvDebug); + mInfoButton = (TextView) view.findViewById(R.id.tvInfo); + mWarnButton = (TextView) view.findViewById(R.id.tvWarn); + mErrorButton = (TextView) view.findViewById(R.id.tvError); + + // Setup label views + mLabel.setBackgroundColor(setup.getBackgroundColor()); + mLabelErrors.setBackgroundColor(setup.getBackgroundColor()); + + // Setup buttons and set listeners mCollapseExpandButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mExpanded = !mExpanded; - updateViewState(); + updateViewState(false); updateExpandButtonIcon(); } }); updateExpandButtonIcon(); - updateErrorButtonIcon(showErrorsOnly); - mRecyclerView = (RecyclerView)view.findViewById(R.id.rvLogs); - mLabel = (TextView)view.findViewById(R.id.tvLabel); - mLabelErrors = (TextView)view.findViewById(R.id.tvLabelError); - mLabel.setBackgroundColor(setup.getBackgroundColor()); - mLabelErrors.setBackgroundColor(setup.getBackgroundColor()); + updateFilterButtonIcon(minimumVisibleLogPriority); + mLLFilters.setVisibility(View.GONE); + mFilterButton.setOnClickListener(new OnClickListener() + { + @Override + public void onClick(View v) + { + mLLFilters.setVisibility(mLLFilters.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); + updateViewState(true); + } + }); + OnClickListener filterClickListener = new OnClickListener() + { + @Override + public void onClick(View v) + { + int priority = Log.VERBOSE; + if (v.getId() == R.id.tvVerbose) + priority = Log.VERBOSE; + else if (v.getId() == R.id.tvDebug) + priority = Log.DEBUG; + else if (v.getId() == R.id.tvInfo) + priority = Log.INFO; + else if (v.getId() == R.id.tvWarn) + priority = Log.WARN; + else if (v.getId() == R.id.tvError) + priority = Log.ERROR; + mFilterChangedListener.onFilterChanged(priority); + updateErrorFilter(priority); + mLLFilters.setVisibility(View.GONE); + updateViewState(true); + } + }; + mVerboseButton.setOnClickListener(filterClickListener); + mDebugButton.setOnClickListener(filterClickListener); + mInfoButton.setOnClickListener(filterClickListener); + mWarnButton.setOnClickListener(filterClickListener); + mErrorButton.setOnClickListener(filterClickListener); // Setup RecyclerView - mAdapter = new LogAdapter(mMinimumLogPriority, showErrorsOnly); + mAdapter = new LogAdapter(minimumVisibleLogPriority); final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); linearLayoutManager.setStackFromEnd(true); mRecyclerView.setLayoutManager(linearLayoutManager); @@ -112,21 +165,21 @@ public void onScrollStateChanged(RecyclerView recyclerView, int newState) addView(view); // Attach and display View - mWindowManager.addView(this, calcWindowParams()); + mWindowManager.addView(this, calcWindowParams(false)); } private void updateLabels(Integer index) { if (index == null) index = ((LinearLayoutManager)mRecyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition(); - mLabel.setText(mLabel.getContext().getString(mShowErrorsOnly ? R.string.lumberjack_overlay_label_errors_only : R.string.lumberjack_overlay_label, index + 1, mAdapter.getItemCount())); - mLabelErrors.setVisibility(!mShowErrorsOnly && mErrors > 0 ? View.VISIBLE : View.GONE); + mLabel.setText(mLabel.getContext().getString(R.string.lumberjack_overlay_label, index + 1, mAdapter.getItemCount())); + mLabelErrors.setVisibility(mErrors > 0 ? View.VISIBLE : View.GONE); mLabelErrors.setText(mErrors > 0 ? mLabelErrors.getContext().getString(R.string.lumberjack_overlay_label_errors, mErrors) : ""); } public void checkOrientation(int orientation) { - updateViewState(); + updateViewState(false); } private void updateExpandButtonIcon() @@ -134,18 +187,37 @@ private void updateExpandButtonIcon() mCollapseExpandButton.setImageResource(mExpanded ? R.drawable.ic_collapse_circle : R.drawable.ic_expand_circle); } - private void updateErrorButtonIcon(boolean showErrorsOnly) + private void updateFilterButtonIcon(int minimumVisibleLogPriority) { - mErrorButton.setImageResource(showErrorsOnly ? R.drawable.ic_error_outline_circle : R.drawable.ic_error_outline_circle_disabled); + String label = ""; + switch (minimumVisibleLogPriority) + { + case Log.VERBOSE: + label = "V"; + break; + case Log.DEBUG: + label = "D"; + break; + case Log.INFO: + label = "I"; + break; + case Log.WARN: + label = "W"; + break; + case Log.ERROR: + label = "E"; + break; + } + mFilterButton.setText(label); } - private void updateViewState() + private void updateViewState(boolean disableAnimations) { - mWindowManager.updateViewLayout(this, calcWindowParams()); mRecyclerView.setVisibility(mExpanded ? View.VISIBLE : View.GONE); + mWindowManager.updateViewLayout(this, calcWindowParams(disableAnimations)); } - private WindowManager.LayoutParams calcWindowParams() + private WindowManager.LayoutParams calcWindowParams(boolean disableAnimations) { Point windowDimen = new Point(); mWindowManager.getDefaultDisplay().getSize(windowDimen); @@ -154,19 +226,40 @@ private WindowManager.LayoutParams calcWindowParams() int desiredLayoutHeight = dpToPx(getContext(), mSetup.getOverlayHeight()); if (!mExpanded) desiredLayoutHeight = buttonHeight; + if (mLLFilters.getVisibility() == View.VISIBLE) + desiredLayoutHeight += 5 * buttonHeight; int layoutHeight = desiredLayoutHeight < windowDimen.y ? desiredLayoutHeight : windowDimen.y; - WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, layoutHeight, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); - windowParams.gravity = Gravity.TOP | Gravity.LEFT; - windowParams.x = 0; - windowParams.y = windowDimen.y - layoutHeight; + lp.gravity = Gravity.TOP | Gravity.LEFT; + lp.x = 0; + lp.y = windowDimen.y - layoutHeight; + + // Deactivate animations + if (disableAnimations) + { + lp.windowAnimations = 0; + Field field = null; + try + { + field = WindowManager.LayoutParams.class.getDeclaredField("privateFlags"); + field.setAccessible(true); + int flag = field.getInt(lp); + flag |= 0x00000040; + field.set(lp, flag); + } catch (NoSuchFieldException e) + { + } catch (IllegalAccessException e) + { + } + } - return windowParams; + return lp; } private int dpToPx(Context context, int dp) @@ -190,15 +283,14 @@ void hideView() void showView() { - mWindowManager.addView(this, calcWindowParams()); + mWindowManager.addView(this, calcWindowParams(false)); } - void updateErrorFilter(boolean showErrorsOnly) + void updateErrorFilter(int minimumVisibleLogPriority) { - mShowErrorsOnly = showErrorsOnly; - mAdapter.setFiltered(showErrorsOnly); + mAdapter.setFiltered(minimumVisibleLogPriority); updateLabels(mAdapter.getItemCount() - 1); - updateErrorButtonIcon(showErrorsOnly); + updateFilterButtonIcon(minimumVisibleLogPriority); } View getCloseButton() @@ -206,13 +298,13 @@ View getCloseButton() return mCloseButton; } - View getErrorButton() + View getPauseButton() { - return mErrorButton; + return mPauseButton; } - View getPauseButton() + public interface IFilterChangedListener { - return mPauseButton; + void onFilterChanged(int priority); } } diff --git a/library-overlay/src/main/res/drawable/bg_circle.xml b/library-overlay/src/main/res/drawable/bg_circle.xml new file mode 100644 index 0000000..c6599db --- /dev/null +++ b/library-overlay/src/main/res/drawable/bg_circle.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/library-overlay/src/main/res/layout/overlay.xml b/library-overlay/src/main/res/layout/overlay.xml index c624967..3b8fee2 100644 --- a/library-overlay/src/main/res/layout/overlay.xml +++ b/library-overlay/src/main/res/layout/overlay.xml @@ -13,26 +13,92 @@ android:layout_height="wrap_content"> - + + + + + + + + + + + + + + + + + + + @@ -60,8 +126,9 @@ + android:layout_height="match_parent"> diff --git a/library-overlay/src/main/res/values/strings.xml b/library-overlay/src/main/res/values/strings.xml index eb040be..1b28685 100644 --- a/library-overlay/src/main/res/values/strings.xml +++ b/library-overlay/src/main/res/values/strings.xml @@ -2,7 +2,6 @@ Log: %1$d/%2$d - Error: %1$d/%2$d (Errors: %1$d)