# 工具类

### LogUtils

```java
import android.util.Log;

/**
 * @author feathers
 * Log Utils
 */
public class LogUtils {
    /** 日志输出级别NONE */
    public static final int LEVEL_NONE = 0;
    /** 日志输出级别E */
    public static final int LEVEL_ERROR =1;
    /** 日志输出级别W */
    public static final int LEVEL_WARN = 2;
    /** 日志输出级别I */
    public static final int LEVEL_INFO = 3;
    /** 日志输出级别D */
    public static final int LEVEL_DEBUG = 4;
    /** 日志输出级别V */
    public static final int LEVEL_VERBOSE = 5;

    /** 日志输出时的TAG */
    private static final String mTag = "LogUtils";
    /** 是否允许输出log */
    private static int mDebuggable = LEVEL_VERBOSE;

    /** 以级别为 v 的形式输出LOG */
    public static void v(String msg) {
        if (mDebuggable >= LEVEL_VERBOSE) {
            Log.v(mTag, msg);
        }
    }

    /** 以级别为 d 的形式输出LOG */
    public static void d(String msg) {
        if (mDebuggable >= LEVEL_DEBUG) {
            Log.d(mTag, msg);
        }
    }

    /** 以级别为 i 的形式输出LOG */
    public static void i(String msg) {
        if (mDebuggable >= LEVEL_INFO) {
            Log.i(mTag, msg);
        }
    }

    /** 以级别为 w 的形式输出LOG */
    public static void w(String msg) {
        if (mDebuggable >= LEVEL_WARN) {
            Log.w(mTag, msg);
        }
    }

    /** 以级别为 w 的形式输出Throwable */
    public static void w(Throwable tr) {
        if (mDebuggable >= LEVEL_WARN) {
            Log.w(mTag, "", tr);
        }
    }

    /** 以级别为 w 的形式输出LOG信息和Throwable */
    public static void w(String msg, Throwable tr) {
        if (mDebuggable >= LEVEL_WARN && null != msg) {
            Log.w(mTag, msg, tr);
        }
    }

    /** 以级别为 e 的形式输出LOG */
    public static void e(String msg) {
        if (mDebuggable >= LEVEL_ERROR) {
            Log.e(mTag, msg);
        }
    }

    /** 以级别为 e 的形式输出Throwable */
    public static void e(Throwable tr) {
        if (mDebuggable >= LEVEL_ERROR) {
            Log.e(mTag, "", tr);
        }
    }

    /** 以级别为 e 的形式输出LOG信息和Throwable */
    public static void e(String msg, Throwable tr) {
        if (mDebuggable >= LEVEL_ERROR && null != msg) {
            Log.e(mTag, msg, tr);
        }
    }

    //指定tag为类名称

    /** 以级别为 v 的形式输出LOG */
    public static void v(Object tag, String msg) {
        if (mDebuggable >= LEVEL_VERBOSE) {
            Log.v(tag.getClass().getSimpleName(), msg);
        }
    }

    /** 以级别为 d 的形式输出LOG */
    public static void d(Object tag, String msg) {
        if (mDebuggable >= LEVEL_DEBUG) {
            Log.d(tag.getClass().getSimpleName(), msg);
        }
    }

    /** 以级别为 i 的形式输出LOG */
    public static void i(Object tag, String msg) {
        if (mDebuggable >= LEVEL_INFO) {
            Log.i(tag.getClass().getSimpleName(), msg);
        }
    }

    /** 以级别为 w 的形式输出LOG */
    public static void w(Object tag, String msg) {
        if (mDebuggable >= LEVEL_WARN) {
            Log.w(tag.getClass().getSimpleName(), msg);
        }
    }

    /** 以级别为 w 的形式输出Throwable */
    public static void w(Object tag, Throwable tr) {
        if (mDebuggable >= LEVEL_WARN) {
            Log.w(tag.getClass().getSimpleName(), "", tr);
        }
    }

    /** 以级别为 w 的形式输出LOG信息和Throwable */
    public static void w(Object tag, String msg, Throwable tr) {
        if (mDebuggable >= LEVEL_WARN && null != msg) {
            Log.w(tag.getClass().getSimpleName(), msg, tr);
        }
    }

    /** 以级别为 e 的形式输出LOG */
    public static void e(Object tag,String msg) {
        if (mDebuggable >= LEVEL_ERROR) {
            Log.e(tag.getClass().getSimpleName(), msg);
        }
    }

    /** 以级别为 e 的形式输出Throwable */
    public static void e(Object tag, Throwable tr) {
        if (mDebuggable >= LEVEL_ERROR) {
            Log.e(tag.getClass().getSimpleName(), "", tr);
        }
    }

    /** 以级别为 e 的形式输出LOG信息和Throwable */
    public static void e(Object tag, String msg, Throwable tr) {
        if (mDebuggable >= LEVEL_ERROR && null != msg) {
            Log.e(tag.getClass().getSimpleName(), msg, tr);
        }
    }
}
```

### ToastUtils

```java
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.StringRes;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.feathers.utils.app.AppContext;

/**
 * Toast统一管理类
 * Created by feathers on 16-9-23.
 * @author feathers
 */
public class ToastUtils {

    private ToastUtils() {
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    public static boolean isShow = true;

    /**
     * 短时间显示Toast
     *
     * @param message
     */
    public static void showShort(CharSequence message) {
        if (isShow)
            Toast.makeText(AppContext.getContext(), message, Toast.LENGTH_SHORT).show();
    }

    /**
     * 短时间显示Toast
     *
     * @param message
     */
    public static void showShort(@StringRes int message) {
        if (isShow)
            Toast.makeText(AppContext.getContext(), message, Toast.LENGTH_SHORT).show();
    }

    /**
     * 长时间显示Toast
     *
     * @param message
     */
    public static void showLong(CharSequence message) {
        if (isShow)
            Toast.makeText(AppContext.getContext(), message, Toast.LENGTH_LONG).show();
    }

    /**
     * 长时间显示Toast
     *
     * @param message
     */
    public static void showLong(@StringRes int message) {
        if (isShow)
            Toast.makeText(AppContext.getContext(), message, Toast.LENGTH_LONG).show();
    }

    /**
     * 自定义显示Toast时间
     *
     * @param message
     * @param duration
     */
    public static void show(CharSequence message, int duration) {
        if (isShow)
            Toast.makeText(AppContext.getContext(), message, duration).show();
    }

    /**
     * 自定义显示Toast时间
     *
     * @param message
     * @param duration
     */
    public static void show(@StringRes int message, int duration) {
        if (isShow)
            Toast.makeText(AppContext.getContext(), message, duration).show();
    }

    /**
     * 展示一个特定布局的Toast(短时间)
     *
     * @param message       要展示的信息
     * @param viewResLayout 整个Toast的布局
     * @param tvResId       要展示message的textView(或者是他的子类),注意：参数3不会主动将view加入到toast layout中
     */
    public static void showShort(CharSequence message, @LayoutRes int viewResLayout, @IdRes int tvResId) {
        View v = ResourceUtils.inflate(viewResLayout);
        Toast toast = new Toast(AppContext.getContext());
        TextView tv = (TextView) v.findViewById(tvResId);
        tv.setText(message);
        toast.setView(v);
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(长)
     *
     * @param message       要展示的信息
     * @param viewResLayout 整个Toast的布局
     * @param tvResId       要展示message的textView(或者是他的子类),注意：参数3不会主动将view加入到toast layout中
     */
    public static void showLong(CharSequence message, @LayoutRes int viewResLayout, @IdRes int tvResId) {
        View v = ResourceUtils.inflate(viewResLayout);
        Toast toast = new Toast(AppContext.getContext());
        TextView tv = (TextView) v.findViewById(tvResId);
        tv.setText(message);
        toast.setView(v);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(短时间)
     *
     * @param message       要展示的信息
     * @param viewResLayout 整个Toast的布局
     * @param tvResId       要展示message的textView(或者是他的子类),注意：参数3不会主动将view加入到toast layout中
     */
    public static void showShort(@StringRes int message, @LayoutRes int viewResLayout, @IdRes int tvResId) {
        View v = ResourceUtils.inflate(viewResLayout);
        Toast toast = new Toast(AppContext.getContext());
        TextView tv = (TextView) v.findViewById(tvResId);
        tv.setText(message);
        toast.setView(v);
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(长)
     *
     * @param message       要展示的信息
     * @param viewResLayout 整个Toast的布局
     * @param tvResId       要展示message的textView(或者是他的子类),注意：参数3不会主动将view加入到toast layout中
     */
    public static void showLong(@StringRes int message, @LayoutRes int viewResLayout, @IdRes int tvResId) {
        View v = ResourceUtils.inflate(viewResLayout);
        Toast toast = new Toast(AppContext.getContext());
        TextView tv = (TextView) v.findViewById(tvResId);
        tv.setText(message);
        toast.setView(v);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(短时间)
     *
     * @param message       要展示的信息
     * @param view toast的布局
     */
    public static void showShort(CharSequence message, View view) {
        Toast toast = new Toast(AppContext.getContext());
        toast.setView(view);
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(长)
     *
     * @param message       要展示的信息
     * @param view  Toast的布局
     */
    public static void showLong(CharSequence message, View view) {
        Toast toast = new Toast(AppContext.getContext());
        toast.setView(view);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(短时间)
     *
     * @param message       要展示的信息
     * @param view toast的布局
     */
    public static void showShort(@StringRes int message, View view) {
        Toast toast = new Toast(AppContext.getContext());
        toast.setView(view);
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.show();
    }

    /**
     * 展示一个特定布局的Toast(长)
     *
     * @param message       要展示的信息
     * @param view  Toast的布局
     */
    public static void showLong(@StringRes int message, View view) {
        Toast toast = new Toast(AppContext.getContext());
        toast.setView(view);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.show();
    }
}
```

### DensityUtils

```java
/**
 * 常用单位转换类
 * Created by feathers on 16-9-23.
 *
 * @author feathers
 */
public class DensityUtils {
    private DensityUtils() {
        /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /**
     * dp转px
     *
     * @param dpVal
     * @return
     */
    public static int dp2px(float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, AppContext.getContext().getResources().getDisplayMetrics());
    }

    /**
     * sp转px
     *
     * @param spVal
     * @return
     */
    public static int sp2px(float spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, AppContext.getContext().getResources().getDisplayMetrics());
    }

    /**
     * px转dp
     *
     * @param pxVal
     * @return
     */
    public static float px2dp(float pxVal) {
        final float scale = AppContext.getContext().getResources().getDisplayMetrics().density;
        return (pxVal / scale);
    }

    /**
     * px转sp
     *
     * @param pxVal
     * @return
     */
    public static float px2sp(float pxVal) {
        return (pxVal / AppContext.getContext().getResources().getDisplayMetrics().scaledDensity);
    }

}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yangsx95.gitbook.io/notes/front-end/android/gong-ju-lei.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
