preface


“All roads lead to Rome.” At work, there is often no unique way to achieve a requirement. These different ways not only show the quality of the code, but also affect our work efficiency. In Android, for example, there are some little-known apis that can reduce the amount of work we do. Therefore, I want to rely on some experience, sort out some commonly used, find a place to sum up, but also for the future read.

getResources().getIdentifier(String name, String defType, String defPackage)


Obtain the resource ID based on the resource name. Normally, we would get the resource directly in our code based on the resource ID, such as:

getResources().getDrawable(R.drawable.ic_launcher);Copy the code

Sometimes, however, resources are not fixed and need to be dynamically selected from multiple resources of the same type according to their usage, such as the interface data that the server passes to the client. What to do? Set up a hard-coded mapping array? Too complicated! You might as well use this method.

A complete resource named package:type/entry corresponds to the three parameters of the method: resource name, resource type, and application package name. A few examples:

imageView.setImageResource(getResources().getIdentifier("ic_launcher"."drawable", getPackageName()));

radioGroup.check(getResources().getIdentifier("rb_indicator_" + position, "id", getPackageName()));Copy the code

In practice, the first parameter name, that is, the resource name, is dynamically set as required, which requires multiple resources to keep a certain standard format when naming. Also, it is important to note that obtaining resources directly by ID is more efficient than obtaining resources by name, so this method is not recommended unless there is such a special need.

TextUtils.isEmpty(CharSequence str)


Empty method using ultra high frequency strings, returns a Boolean value, the judgment of the internal implementation conditions as follows: STR = = null | | STR. The length () = = 0. A developer’s favorite if string judgment, the system has been wrapped for us.

Html.fromHtml()


Parses rich text content in Html format and returns a styled string to be displayed by controls such as TextView. It can solve the display problem of rich text content containing hyperlink, text and text mix.

DateUtils.formatDateTime()


Using the Date utility class provided by the Android SDK, you can format millisecond time data of type LONG into a string in a specific display format. Usually we use SimpleDateFormat in the Java SDK to format date data, such as new SimpleDateFormat(” YYYY-MM-DD HH: MM “).format(), What DateUtils does is encapsulate this process for us. The formatting result depends on the local locale of the current device. Here are a few common formats (in Chinese) :

  • FORMAT_SHOW_DATE: March 3
  • FORMAT_SHOW_TIME: he who
  • FORMAT_SHOW_WEEKDAY: Friday
  • FORMAT_SHOW_YEAR: March 3, 2017
  • FORMAT_NUMERIC_DATE: 3/3
  • March FORMAT_NO_MONTH_DAY:

Formatter.formatFileSize(Context context, long sizeBytes)


Format the file size to format byte data into B, KB, and M units. The context parameter is used to determine the order of strings to be returned, right-to-left or left-to-right. This utility class saves us from converting our own calculations, which is very handy, especially for similar scenarios like in-app file downloads.

TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics)


Converts the size data of the specified unit into the corresponding pixel value based on the current device screen information. Where TypedValue provides a common unit value for the first parameter, such as:

  • COMPLEX_UNIT_PX
  • COMPLEX_UNIT_DIP
  • COMPLEX_UNIT_PT
  • COMPLEX_UNIT_SP

The source code is as follows:

public static float applyDimension(int unit, float value, DisplayMetrics metrics){
    switch (unit) {
    case COMPLEX_UNIT_PX:
        return value;
    case COMPLEX_UNIT_DIP:
        return value * metrics.density;
    case COMPLEX_UNIT_SP:
        return value * metrics.scaledDensity;
    case COMPLEX_UNIT_PT:
        return value * metrics.xdpi * (1.0 f/72);
    case COMPLEX_UNIT_IN:
        return value * metrics.xdpi;
    case COMPLEX_UNIT_MM:
        return value * metrics.xdpi * (1.0 f/25.4 f);
    }
    return 0;
}Copy the code

In practice, pixel values are int integers, and this method returns a float, which will automatically discard the decimal part if cast directly. So, if we don’t use this method, we usually convert like this:

public static int convertDipToPx(Context context, int dip) {
    float scale = context.getResources().getDisplayMetrics().density;
    // 0.5f is used to round up
    return (int) (dip * scale + 0.5 f * (dip >= 0 ? 1 : -1));
}Copy the code

Space


The official notes are as follows:

Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.

Space is a lightweight View for creating gaps between views. No drawing is performed in the onDraw() method, so android:background doesn’t work for him. Usually we use views to create gaps between views, and Spaces are actually more efficient without regard to background colors. Note that since the controls are introduced in API 14, you need to use the Support V4 package if you want forward compatibility.

view.performClick()


Automatically call the View click event. Usually the button and other controls can only trigger the click event when the user clicks. This method can simulate the user click behavior by triggering some special conditions. Similarly, the performLongClick() method.

Log.getStackTraceString(Throwable tr)


A common static method provided by the Log class, unlike common methods such as log.i () that print logs to the Logcat console, this method takes an error message from a Throwable object and returns it as a string. This is handy when you need to persist error messages, such as saving them to a local memory card or uploading them to a server.

Linkify.addLinks()


We know that the Android :autoLink property can be used to add hyperlink click events with fixed templates such as Web and phone to the content in the TextView text control. However, after all, the system templates are limited, and the method of linkify.addLinks () can be used to add some custom templates in the application, such as the hyperlink jump in the format of “@xxx” in Sina Weibo, which can be matched by custom regular expressions.

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE)


Set the security window to disable system screenshots. Prevent some interfaces in the App from being screenshot and displayed in other devices, resulting in information leakage. (To capture a screen shot on a common mobile device, press the power button and the volume button simultaneously.)

For example, alipay App’s “Payment to merchants” interface contains the QR code of payment. (It should be added that wechat payment interface does not do this. Instead, it uses the onResume() life-cycle method to refresh the QR code of payment in real time, which is different from alipay’s security method.)

Block the Back key to put the App in the background instead of closing it


  @Override
  public void onBackPressed(a) {
    Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
    launcherIntent.addCategory(Intent.CATEGORY_HOME);
    startActivity(launcherIntent);
  }Copy the code

Use the Back key to return to the desktop, but instead of closing the current app, put it in the background, just like pressing the Home button.

That’s a great technique. Generally, in order to prevent users from quitting the App by mistake by pressing the Back button, we will monitor the Back button operation in the Activity of the home page of the application and give users a reconfirmation operation by using Toast weak prompt or even Dialog strong prompt, but it cannot prevent users from gradually closing the App by using the Back button.

However, using this method to block the last Activity of the App (usually the home screen), without blocking the user (back to the desktop) or shutting down the App (running in the background), indirectly increasing the App’s lifetime, is a real trick. And according to my experiment, wechat, Alipay, Weibo and other apps are doing so, you might as well try.

ThumbnailUtils


Thumbnail tool class, which can generate thumbnails based on local video file sources and Bitmap objects. Common public static methods are:

  • createVideoThumbnail(String filePath, int kind)
  • extractThumbnail(Bitmap source, int width, int height)

bitmap.extractAlpha()


Gets a new bitmap object from the source bitmap according to alpha. Compared with the winding, most ICONS in the App are composed of solid color transparent pixel background. This method can be used to color the opaque area of the graph. There are various application scenarios, such as Button pressed state, View shadow state, etc. Here’s an example:

private static Bitmap getDropShadow(ImageView iv, Bitmap src, float radius, int color) {

    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(color);

    final int width = src.getWidth(), height = src.getHeight();
    final Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(dest);
    final Bitmap alpha = src.extractAlpha();
    canvas.drawBitmap(alpha, 0.0, paint);

    final BlurMaskFilter filter = new BlurMaskFilter(radius, BlurMaskFilter.Blur.OUTER);
    paint.setMaskFilter(filter);
    canvas.drawBitmap(alpha, 0.0, paint);
    iv.setImageBitmap(dest);

    return dest;
}Copy the code

ArgbEvaluator


A TypeEvaluator provided by the system, we only need to provide two starting color values and a score value, and the system calculates a new intermediate color value through a specific algorithm. With this class, we can do at least two things.

First, used in property animation. As it implements the TypeEvaluator interface, it can be used as an evaluator to animate custom properties and change the display state of a View. Such as:

int colorStart = ContextCompat.getColor(this, R.color.black);
int colorEnd = ContextCompat.getColor(this, R.color.green);
ValueAnimator valueAnimator = ValueAnimator
    .ofObject(new ArgbEvaluator(), colorStart, colorEnd)
    .setDuration(3000);
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) { textView.setTextColor((Integer) animation.getAnimatedValue()); }}); valueAnimator.start();Copy the code

Second, the color evaluation algorithm provided by this class is used in conjunction with the slide deviation value provided by ViewPager. This scenario is common in bootpages implemented using ViewPager, where the background color changes dynamically with the sliding distance; Tab style menu page using ViewPager, Tab text dynamically changes font color with sliding distance (please refer to wechat android version). Both of these uses make the transitions between ViewPager pages very natural and enjoyable. Such as:

viewPager.addOnPageChangeListener(new OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        new ArgbEvaluator().evaluate(positionOffset, startColor, endColor);
    }

    @Override
    public void onPageSelected(int position) {}@Override
    public void onPageScrollStateChanged(int state) {}});Copy the code

In addition, for the calculation of color difference, There is another algorithm in Google Sample, please refer to slidingTabstrip. Java file source code, and the core method content is as follows:


/**
* Blend {@code color1} and {@code color2} using the given ratio.
*
* @paramRatio of which to blend.1.0 will return {@codeColor1}, 0.5 will give an even blend, * 0.0 will return {@code color2}.
*/
private static int blendColors(int color1, int color2, float ratio) {
    final float inverseRation = 1f - ratio;
    float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
    float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
    float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
    return Color.rgb((int) r, (int) g, (int) b);
}Copy the code

android:weightSum


Used in the LinearLayout to set the total weight of Children weight. In the children of LinearLayout, we often use Android :layout_weight to allocate the space of the container layout proportionally, but sometimes it may not be finished. In the past, some friends might use an empty space at the end to achieve a placeholder effect at the end. If you know this property, you can write less code.

android:descendantFocusability


Used in ViewGroup to solve the focus occupation problem between the Parent ViewGroup and the Children View. The most common use scenario is a list item containing some click effect controls, such as Button, CheckBox, I believe we have encountered. There are three values, but I don’t need to say more about them:

  • afterDescendants
  • beforeDescendants
  • blocksDescendants

android:duplicateParentState


Whether to hand the View’s drawable state to the parent ViewGroup. The value is a Boolean. For example, if you have an item layout and there is a button in the item Layout, you can use this property in the button if you click on the item Layout and want the button to display the corresponding click effect. However, from a design perspective, this scenario is relatively rare. It is good to know that this property is present, and not recommended for interaction design.

android:fillViewport


A property of ScrollView that sets whether the content portion fills the screen, especially if the content does not fill the screen. Here’s a tip to use, referring to my previous article: Two very useful layout tips for everyday Android development.

android:adjustViewBounds


When using ImageView, you may use the Android :scaleType property to set the image scale. The Android :adjustViewBounds property works similarly. Note, however, that the latter needs to specify at least one attribute of the ImageView width, or something like maxHeight, and then the other attribute matches. This property is suitable for lists, such as the active list page in an App, where the image width is match_parent and the height is wrap_content to make it adaptive so that high-resolution images taken from the service don’t get stretched across different screens. (Note: it’s best to place a default image with the same size as the web image in the project resource file, in the placeholder role, to avoid the bad experience of image display height being 0.)

Continuously updated…


This article first remember so much, accumulate over a long period of time, in the follow-up continuous update, please pay attention to… (Of course, if you have any efficient and rare API, please share with us.)

Welcome to follow my wechat official account


Android Notebook: Focuses on Android development and the path of programmers.