Tag: Rewrite the structure. com ram share. net to get data add SQL

Original address: http://blog.csdn.net/guolin_blog/article/details/44996879

 

Of all the common native controls used by Android, the most complex use is ListView, which is designed to handle situations where there are so many elements of that content that the phone screen can’t display everything. ListView can display content in the form of a list, beyond the screen.Some of the content can only be moved to the screen by sliding fingers.

 

And ListView has a fantastic feature that I’m sure you’ve all experienced. Even if you load a lot of data in ListView, like hundreds or more, the ListView won’t have OOM or crash, and with our fingersWhen slipping to browse more data, the memory occupied by the program will never increase. So how did ListView achieve such a magical function? I spent a lot of time reading through the source code of ListView with a learning mindset and basically understood how it works.I was also awed by the fact that Google could write such exquisite code, because ListView had so much code and complexity that it was hard to write clearly in words, so I gave up the idea of writing it as a blog. Now, in retrospect, I already have this matter.My bowels were blue with regret, because in a few months I had forgotten all the source code that had been sorted out. So now I’ve set my mind to reread the ListView source again, and this time I’m going to write it as a blog, share it with everyone and treat it as my own.Take notes.

First, let’s look at the inheritance structure of ListView, as shown in the following figure:

 

Technology sharing

As you can see, ListView’s inheritance structure is still fairly complex, it’s directly inherited from the AbsListView, and AbsListView has two subimplementation classes, one is ListView and the other is GridView, so we’re from this pointYou can guess that ListView and GridView have a lot in common in terms of their work principles and implementations. Then AbsListView inherits from AdapterView, AdapterView inherits from ViewGroup, and then comes back.What we are familiar with. First, let’s have a look at the inheritance structure of ListView, which will help us to analyze the code more clearly later.

 

 

AdapterRole

 

 

AdapterI believe you will not be strange, we usually use ListView when we will use it. Then, have you ever thought about why you need Adapter? I always feel that because of Adapter, the use of ListView has become more than that.Other controls are much more complicated. So let’s first learn about what role Adapter played.

 

In the final analysis, controls are designed to interact with and display data, but ListView is even more special. It’s designed to show a lot of data, but ListView is only responsible for interaction and presentation. ListView doesn’t care where the data comes from.. So the most basic ListView mode of operation we can imagine is having a ListView control and a data source.

 

But if you really get ListView to work directly with the data source, then the adaptation of ListView is very complicated. Because the concept of a data source is so vague, we only know that it contains a lot of data, and we don’t know what type of data source it is.Strict definitions can be arrays, collections, or even cursors queried in database tables. So if ListView really adapts for each data source, the scalability is poor, with only a few built-in adapters, and noAdd dynamically. The second is that it goes beyond the scope of its own responsibilities and is no longer just responsible for interaction and presentation, so the ListView becomes bloated.

 

Obviously the Android development team won’t allow this to happen, so there’s a mechanism like Adapter. As the name implies, Adapter is the adapter that acts as a bridge between ListView and the data source, LisInstead of working directly with the data source, the tView uses the Adapter bridge to access the real data source. Unlike before, the Adapter interface is uniform, so the ListView no longer has to worry about any aspects of adaptation. And AdapIt is also an interface that implements a variety of subclasses, each of which can perform specific functions through its own logic, and adapts to specific data sources, such as Array Adapter for arrays and List typesData source adaptation, SimpleCursor Adapter, can be used for cursor type data source adaptation, which is very clever to solve the problem of difficult data source adaptation, and also has a fairly good scalability. The schematic diagram of the simple principle is as follows:

Technology sharing

Of course, the role of Adapter is not just to adapt data sources, there is also a very important method that we need to rewrite in Adapter, that is, the getView () method, which will be discussed in more detail in the following article.

 

RecycleBinmechanism

 

So before we start analyzing the source code for ListView, one more thing we need to know beforehand is the RecycleBin mechanism, which is one of the most important reasons ListView can implement hundreds of pieces of data without OOM. In fact, RecycLeBin doesn’t have much code, only about 300 lines, and it’s an internal class written in AbsListView, so all the subclasses that inherit from AbsListView, namely ListView and GridView, can use this mechanism. Then weTake a look at the main code in RecycleBin.

/**
 * The RecycleBin facilitates reuse of views across layouts. The RecycleBin
 * has two levels of storage: ActiveViews and ScrapViews. ActiveViews are
 * those views which were onscreen at the start of a layout. By
 * construction, they are displaying current information. At the end of
 * layout, all views in ActiveViews are demoted to ScrapViews. ScrapViews
 * are old views that could potentially be used by the adapter to avoid
 * allocating views unnecessarily.
 * 
 * @see android.widget.AbsListView#setRecyclerListener(android.widget.AbsListView.RecyclerListener)
 * @see android.widget.AbsListView.RecyclerListener
 */
class RecycleBin {
	private RecyclerListener mRecyclerListener;

	/**
	 * The position of the first view stored in mActiveViews.
	 */
	private int mFirstActivePosition;

	/**
	 * Views that were on screen at the start of layout. This array is
	 * populated at the start of layout, and at the end of layout all view
	 * in mActiveViews are moved to mScrapViews. Views in mActiveViews
	 * represent a contiguous range of Views, with position of the first
	 * view store in mFirstActivePosition.
	 */
	private View[] mActiveViews = new View[0];

	/**
	 * Unsorted views that can be used by the adapter as a convert view.
	 */
	private ArrayList<View>[] mScrapViews;

	private int mViewTypeCount;

	private ArrayList<View> mCurrentScrap;

	/**
	 * Fill ActiveViews with all of the children of the AbsListView.
	 * 
	 * @param childCount
	 *            The minimum number of views mActiveViews should hold
	 * @param firstActivePosition
	 *            The position of the first view that will be stored in
	 *            mActiveViews
	 */
	void fillActiveViews(int childCount, int firstActivePosition) {
		if (mActiveViews.length < childCount) {
			mActiveViews = new View[childCount];
		}
		mFirstActivePosition = firstActivePosition;
		final View[] activeViews = mActiveViews;
		for (int i = 0; i < childCount; i++) {
			View child = getChildAt(i);
			AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
			// Don‘t put header or footer views into the scrap heap
			if (lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
				// Note: We do place AdapterView.ITEM_VIEW_TYPE_IGNORE in
				// active views.
				// However, we will NOT place them into scrap views.
				activeViews[i] = child;
			}
		}
	}

	/**
	 * Get the view corresponding to the specified position. The view will
	 * be removed from mActiveViews if it is found.
	 * 
	 * @param position
	 *            The position to look up in mActiveViews
	 * @return The view if it is found, null otherwise
	 */
	View getActiveView(int position) {
		int index = position - mFirstActivePosition;
		final View[] activeViews = mActiveViews;
		if (index >= 0 && index < activeViews.length) {
			final View match = activeViews[index];
			activeViews[index] = null;
			return match;
		}
		return null;
	}

	/**
	 * Put a view into the ScapViews list. These views are unordered.
	 * 
	 * @param scrap
	 *            The view to add
	 */
	void addScrapView(View scrap) {
		AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
		if (lp == null) {
			return;
		}
		// Don‘t put header or footer views or views that should be ignored
		// into the scrap heap
		int viewType = lp.viewType;
		if (!shouldRecycleViewType(viewType)) {
			if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
				removeDetachedView(scrap, false);
			}
			return;
		}
		if (mViewTypeCount == 1) {
			dispatchFinishTemporaryDetach(scrap);
			mCurrentScrap.add(scrap);
		} else {
			dispatchFinishTemporaryDetach(scrap);
			mScrapViews[viewType].add(scrap);
		}

		if (mRecyclerListener != null) {
			mRecyclerListener.onMovedToScrapHeap(scrap);
		}
	}

	/**
	 * @return A view from the ScrapViews collection. These are unordered.
	 */
	View getScrapView(int position) {
		ArrayList<View> scrapViews;
		if (mViewTypeCount == 1) {
			scrapViews = mCurrentScrap;
			int size = scrapViews.size();
			if (size > 0) {
				return scrapViews.remove(size - 1);
			} else {
				return null;
			}
		} else {
			int whichScrap = mAdapter.getItemViewType(position);
			if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
				scrapViews = mScrapViews[whichScrap];
				int size = scrapViews.size();
				if (size > 0) {
					return scrapViews.remove(size - 1);
				}
			}
		}
		return null;
	}

	public void setViewTypeCount(int viewTypeCount) {
		if (viewTypeCount < 1) {
			throw new IllegalArgumentException("Can‘t have a viewTypeCount < 1");
		}
		// noinspection unchecked
		ArrayList<View>[] scrapViews = new ArrayList[viewTypeCount];
		for (int i = 0; i < viewTypeCount; i++) {
			scrapViews[i] = new ArrayList<View>();
		}
		mViewTypeCount = viewTypeCount;
		mCurrentScrap = scrapViews[0];
		mScrapViews = scrapViews;
	}

}

 

The RecycleBin code here is not complete. I just put forward the main methods. So let’s start with a simple interpretation of these methods, which will be very helpful for the subsequent analysis of how ListView works.

  • fillActiveViews() This method takes two parameters, the first representing the number of views to store and the second representing the position value of the first visible element in the ListView. RecycleBin uses mActiveViews array to store Vie.W, after calling this method, the specified elements in the ListView are stored in the mActiveViews array based on the parameters passed in.
  • getActiveView() This method corresponds to fillActiveViews (), which is used to get data from the mActiveViews array. This method receives a position parameter that indicates the location of the element in the ListView, and the posi is automatically placed inside the methodThe tion value is converted to the subscript value corresponding to the mActiveViews array. Note that the view stored in the mActiveViews, once retrieved, will be removed from the mActiveViews, and the next time the same view is retrievedIt will return to null, that is to say, mActiveViews can not be reused.
  • addScrapView() Used to cache a discarded View, this method receives a View parameter that should be called to cache the View when a View is determined to be discarded (such as scrolling out of the screen), using mScrapV in RecycleBinThese two List, iews and mCurrentScrap, store View.
  • getScrapView The view in these discarded caches is not sequential, so the getScrapView () method’s algorithm is very simple, which is to get a scrap V directly from the mCurrentScrap tail.Iew returns.
  • setViewTypeCount() We all know that an adapter can override a getViewTypeCount () to represent several types of data items in a ListView, and the setViewTypeCount () method is used to enable each type of data item individuallyA RecycleBin cache mechanism. In fact, the getViewTypeCount () method is not usually used much, so we just need to know that RecycleBin has such a feature.

 

Now that I understand the main methods in RecycleBin and their usefulness, I’ll start to analyze how ListView works, and I’ll do it the same way I used to analyze the source code, that is, follow the main line of execution to read it step by step and point to it, or elseIt is to paste all the code of ListView, so this article will be very long.

 

First time Layout

 

Anyway, ListView will eventually inherit from View even if it’s special, so its execution process will follow the rules of View, and friends unfamiliar with this can refer to what I wrote earlierAndroidThe view drawing process is fully parsed, giving you a step-by-step understanding of View (two). 。

 

ViewThe execution process consists of three steps: onMeasure () for measuring the size of the View, onLayout () for determining the layout of the View, and onDraw () for drawing the View onto the interface. In ListView, onMeasuRe () has nothing special, because it’s ultimately a View that takes up the most space and usually the entire screen. OnDraw () doesn’t make much sense in ListView, because ListView itself isn’t responsible for drawing, it’s a ListThe child elements in View are drawn. So most of the magic of ListView is actually done in the onLayout () method, so this article is also the main analysis of this method.

 

If you look in the ListView source, you will find that there is no onLayout () method in the ListView, because this method is implemented in the ListView parent class AbsListView, the code is as follows:

 

Android ListViewWorking principle is completely parsed (from Guo Lin’s blog).

Tag: Rewrite the structure. com ram share. net to get data add SQL

Original address: http://www.cnblogs.com/ProtectedDream/p/6980195.html

Similar Posts:

Leave a Reply

Your email address will not be published. Required fields are marked *