Unexpectedly, the bitmap algorithm can be applied like this in Android RecyclerView!

1 Introduction

1.1 About the algorithm

The protagonist in Jin Yong's martial arts novels will learn a profound internal skill before becoming a peerless master. Guo Jing had the Quanzhen School of internal skills to cultivate the Jiuyin Scriptures, and after Xuzhu gained Wuyazi's lifelong skills, his martial arts attainments gradually improved, and Zhang Wuji worked hard for five years to practice the Jiuyang magical skills. Only in the future can he integrate the universe and move. For programmers, algorithms are the internal skills in the novel, and programming languages ​​are the martial arts of different schools. Zhang Wuji learned the great shift in the universe that Yang Dingtian could not learn in decades because of the blessing of the Nine Suns. An excellent programmer needs to continuously practice the internal skills of the algorithm in order to obtain higher programming attainments.

1.2 Algorithm&Android series

"Algorithms are rarely used in actual programming, that is, they can be used for interviews in big factories." I believe this sentence is a portrayal of many programmers' misunderstandings about algorithms. In fact, a good algorithm can allow the program to be executed in the fastest time, with minimal memory overhead, and even serve users for a longer period of time. Since the algorithm is so important, how can we learn it well? I think algorithm learning has two pain points. One is I don’t know which algorithms are there, and the other is I know which algorithms are there, but I don’t know how to use them. Algorithm&Android series I will combine the principle of the algorithm and its usage scenarios in Android, and disassemble the algorithms used in the Android source code.

2. Bitmap Algorithm

2.1 Reflection caused by a joke

Going home from get off work last night, a policeman came on patrol. Suddenly yelled to me: Stop!

Police: How many bytes does the int type occupy?

Me: Four.

Police: You can go now.

I was surprised.

Me: Why do you ask such a question?

Police: I was still walking on the street late at night, looking bitter, either a thief or a programmer.

The above jokes are purely spoof, any similarity is purely coincidental. We know that the smallest unit of the program is bit, which is either 0 or 1. The byte is the smallest unit of byte jitter, and a byte is composed of 8 bits. The int type consists of 4 bytes.

Suppose there are 5 int types [0,2,4,5,7]. Then it will consume 20 bytes of computer memory and 160 bits of memory. Assuming there are 500 million different int type numbers, it will cost 500 million*160 bits. About 2G memory. If a bit can represent an int type, then we will save 32 times the memory. Probably need 64M memory.

The traditional storage space is as follows:

Bitmap representation. Assuming that the position value of each bit is 1, it means position. For example, the second bit is 1, which means the value is 2. Then [0,2,4,5,7] can be expressed as follows:

8 bits can represent 5 numbers that originally required 160 bits. Is it very space-saving?

The use of bits and positions to represent numbers is called a bitmap algorithm. Its advantages are:

  1. save space
  2. Quick sort
  3. Quick Search

2.2 Bit operation

  1. Assignment operation mData |= 1 << index
  2. Clear operation mData &= ~(1 << index)
  3. Query operation (mData & (1 << index)) != 0

2.2.1 Assignment operation

2.2.2 Clear operation

2.2.2 Query operation

3. Implementation of bitmap algorithm in Android

3.1 ChildHelper.java

RecyclerView的构造函数,会调用initChildrenHelper()//RecyclerView.java
private void initChildrenHelper() {
    
    
    mChildHelper = new ChildHelper(new ChildHelper.Callback() {
    
    
         //...省略代码                          
    });
}

The main function of ChildHelper is to "logically hide" the child View on RecyclerView. When View does disappear animation, it will call RecyclerView#addAnimatingView(ViewHolder viewHolder) -> mChildHelper.addView(view, true)

//ChildHelper.java
void addView(View child, boolean hidden) {
    
    
    addView(child, -1, hidden);
}

void addView(View child, int index, boolean hidden) {
    
    
    final int offset;
    if (index < 0) {
    
    
        offset = mCallback.getChildCount();
    } else {
    
    
        offset = getOffset(index);
    }
    mBucket.insert(offset, hidden);
    if (hidden) {
    
    
        hideViewInternal(child);
    }
    mCallback.addView(child, offset);
    if (DEBUG) {
    
    
        Log.d(TAG, "addViewAt " + index + ",h:" + hidden + ", " + this);
    }
}

Note that **"mBucket.insert(offset, hidden);"** The Bucket class is the implementation of the bitmap algorithm in the RecyclerView ChildHelper class.

3.2 getChildCount()

RecyclerView has a getChildCount() method, and LayoutManager also has a getChildCount() method. What is the difference between them?

RecyclerView inherits from ViewGroup

//ViewGroup.java
public int getChildCount() {
    
    
    return mChildrenCount;
}

//LayoutManager.java
public int getChildCount() {
    
    
    return mChildHelper != null ? mChildHelper.getChildCount() : 0;
}

//ChildHelper.java
int getChildCount() {
    
    
    return mCallback.getChildCount() - mHiddenViews.size();
}

mChildHelper = new ChildHelper(new ChildHelper.Callback() {
    
    
      @Override
      public int getChildCount() {
    
    
          return RecyclerView.this.getChildCount();
      }
});

We can see that calling the RecyclerView.getChildCount() method returns all the Views on the RecyclerView. Calling LayoutManager.getChildCount() will filter out the View that is doing disappearing animation, such as the Item that has called the notifyItemRemoved(int position) method. Or a View that is squeezed out of the screen and needs to be animated.

Guess you like

Origin blog.csdn.net/A_pyf/article/details/115214869