Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the pitfalls and tricks of Android development?

2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article is to share with you what are the pitfalls and tips for Android development. The editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.

1 、 android:clipToPadding

It means whether the drawing area of the control is in padding. The default is true. If you set this property to false, you can achieve the effect of getting half the effort with half the effort in the layout. Take a look at an effect picture first.

There is a gap at the top of the ListView in the image above by default, and after sliding up, the gap disappears, as shown in the following illustration.

If you use margin or padding, you can't achieve this effect. Adding a headerView is overqualified and too troublesome. The clipToPadding here works just right with paddingTop.

Similarly, there is another magical attribute: android:clipChildren. For more information, please refer to [Android] the magical android:clipChildren attribute (http://www.cnblogs.com/over140/p/3508335.html)).

2. Match_parent and wrap_content

In theory, these two properties are clear at a glance, one is to fill the layout space to adapt to the parent control, and the other is to adapt to the size of its own content. But if you use it incorrectly in a list such as ListView, it will be a big problem. The getView method in ListView needs to calculate the list entries, so it is necessary to determine the height of the ListView before onMesure can do the measurement. If wrap_content is specified, it is tantamount to telling the system that if I have 10, 000 items, you will calculate and display them for me, and then the system will new 10, 000 objects according to your requirements. So you're not tragic? Look at a picture first.

Suppose ListView now has eight pieces of data, match_parent needs to new seven objects, and wrap_content needs eight. The reuse of View is involved here, so I won't discuss it much. So the settings of these two properties will determine the number of calls to getView.

This leads to another problem: getView is called multiple times.

What do you mean multiple calls? For example, position=0 may have been called several times. It seems weird. Both GridView and ListView are possible, and maybe the culprit is wrap_content. In the final analysis, there is something wrong with the layout of View. If the nested View is too complex, the solution can be to measure the required height of the list through code, or to use a trick in getView: parent.getChildCount = = position

@ Override public View getView (int position, View convertView, ViewGroup parent) {if (parent.getChildCount () = = position) {/ / does things here} return convertView;}

3 、 IllegalArgumentException: pointerIndex out of range

The appearance of this Bug scene is still very speechless. At first, I used ViewPager + PhotoView (an open source control) to display pictures, which occurred when I zoomed in and out of multi-touch. At first I suspected it was PhotoView's bug, but I looked for it for a long time to no avail. The fatal thing is that I don't know how to try, always crash. It was later learned that it was the bug left behind by android, and there was no check for pointer index in the source code. It's impossible to change the source code and recompile it. Knowing that there is exception, it can't be solved fundamentally. If we don't let it crash, then we can only try-catch. The solution is to customize a ViewPager and inherit ViewPager. Look at the following code:

/ * Custom wrapper android.support.v4.view.ViewPager, override onInterceptTouchEvent event, catch system-level exception * / public class CustomViewPager extends ViewPager {public CustomViewPager (Context context) {this (context, null);} public CustomViewPager (Context context, AttributeSet attrs) {super (context, attrs) @ Override public boolean onInterceptTouchEvent (MotionEvent ev) {try {return super.onInterceptTouchEvent (ev);} catch (IllegalArgumentException e) {LogUtil.e (e);} catch (ArrayIndexOutOfBoundsException e) {LogUtil.e (e);} return false;}}

Replace the layout file that uses ViewPager with CustomViewPager and OK.

4. There is no response to the item click event in ListView

The Item click event of listView suddenly does not respond, and the problem usually occurs after adding button, checkbox and other controls to the listView. The problem is caused by the focus on conflict. In android, after clicking on the screen, click events will be assigned according to your layout. When you add button to your listView, click events * * to assign priority to the button in your listView. So your click Item is invalid, and you have to set a click event for the outermost layout of your item or add a click event to one of your layout elements according to your needs.

Solution: set the descendantFocusability property in the root control of ListView (if the root control is LinearLayout, add the following property setting in LinearLayout).

Android:descendantFocusability= "blocksDescendants"

This is also stated in the official documentation.

5. GetSupportFragmentManager () and getChildFragmentManager ()

There is a requirement that Fragment needs to nest three Fragment. You can basically think of implementing it with ViewPager. The starting code is written as follows:

MViewPager.setAdapter (new CustomizeFragmentPagerAdapter (getActivity (). GetSupportFragmentManager (), subFragmentList))

The problem is that nested Fragment is sometimes inexplicably not displayed. At first you don't know where the problem is, and when you don't know the cause of the problem, it's obviously troublesome to solve it. After searching again and again, I finally saw the same question on stackoverflow. Just say getChildFragmentManager () is fine. It's so amazing!

MViewPager.setAdapter (new CustomizeFragmentPagerAdapter (getChildFragmentManager, subFragmentList))

Let's see the difference between the two. The first is the description of getSupportFragmentManager (or getFragmentManager):

Return the FragmentManager for interacting with fragments associated with this fragment's activity.

Then there is getChildFragmentManager:

Return a private FragmentManager for placing and managing Fragments inside of this Fragment.

Basically, the difference is that Fragment's now have their own internal FragmentManager that can handle Fragments. The child FragmentManager is the one that handles Fragments contained within only the Fragment that it was added to. The other FragmentManager is contained within the entire Activity.

I've made it quite clear.

6. ScrollView nested ListView

Isn't this a strange design? Two View, which can also scroll, are put together, and they are still nested. There used to be such a requirement: the interface consists of four areas, namely, basic company information (logo, name, legal person, address), company profile, company honor, and company word-of-mouth list. Each part of the content needs to adapt to the height according to the content, can not be written dead. The first thing I think of is that the outside is surrounded by a ScrollView. Then these four parts are encapsulated with four custom controls. Basic information and company profile are relatively simple, honors need to use a combination of RecyclerView and TextView, RecyclerView (of course, you can also use GridView, 3 columns of multi-line display) to store honor pictures, TextView displays honor names. * * part of the word-of-mouth list is ListView, of course. At this point, the problem arises. Need to solve the problem of sliding the ListView into the ScrollView and the display of the RecyclerView (if the height of the RecyclerView cannot be calculated, you can't see the content).

Of course, there are already similar questions and solutions online.

Give a URL:

Four solutions to the ScrollView nested ListView problem (http://bbs.anzhuo.cn/thread-982250-1-1.html))

The case of ListView is relatively easy to solve, and the elegant approach is to write a class that inherits ListView and then overrides the onMeasure method.

Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec (Integer.MAX_VALUE > > 2, MeasureSpec.AT_MOST); super.onMeasure (widthMeasureSpec, expandSpec);}

ListView can rewrite the onMeasure solution, but RecyclerView rewriting this method is not feasible.

In the final analysis, the height is actually calculated. There are two ways, one is to dynamically calculate RecycleView, and then set setLayoutParams; the other is similar to the solution of ListView, define a class to inherit LinearLayoutManager or GridLayoutManager (note: not inherit RecyclerView), rewrite the onMeasure method (this method is troublesome, not shown here, write an article to introduce it next time).

The dynamic calculation height is as follows:

Int heightPx = DensityUtil.dip2px (getActivity (), (imageHeight + imageRowHeight) * lines); MarginLayoutParams mParams = new MarginLayoutParams (LayoutParams.MATCH_PARENT, heightPx); mParams.setMargins (0,0,0,0); LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams (mParams); honorImageRecyclerView.setLayoutParams (lParams)

The idea is like this: after the server returns the honor picture, because it is displayed in three columns, you only need to calculate how many lines need to be displayed, then give the line spacing and the height of the picture, and then set setLayoutParams on it.

Int lines = (int) Math.ceil (totalImages / 3D)

At this point, this strange need has been addressed.

But when sliding, I feel the phenomenon of stutter. Smart, you must have thought of a sliding conflict. It should be that the sliding of ScrollView interferes with the sliding of ListView. What should I do? Can you stop ScrollView from sliding?

Baidu, you are sure to find the answer. Code first:

/ * * @ author Leo * * Created in 2015-9-12 * intercept ScrollView slide events * / public class CustomScrollView extends ScrollView {private int downY; private int touchSlop; public CustomScrollView (Context context) {this (context, null);} public CustomScrollView (Context context, AttributeSet attrs) {this (context, attrs, 0) } public CustomScrollView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); touchSlop = ViewConfiguration.get (context). GetScaledTouchSlop ();} @ Override public boolean onInterceptTouchEvent (MotionEvent e) {int action = e.getAction (); switch (action) {case MotionEvent.ACTION_DOWN: downY = (int) e.getRawY () Break; case MotionEvent.ACTION_MOVE: int moveY = (int) e.getRawY (); if (Math.abs (moveY-downY) > touchSlop) {return true;}} return super.onInterceptTouchEvent (e);}}

As long as you understand the getScaledTouchSlop () method, it's easy to do. The comment for this method is: Distance in pixels a touch can wander before we think the user is scrolling. It is said that this is a distance, which means that when you slide, the movement of the hand should be greater than this distance before you start to move the control. If it is less than this distance, the movement will not be triggered.

It looks like a lot of money.

But there is another problem: every time I load this interface, it takes me too long. Every time I start it from another interface, I get stuck for 1 to 2 seconds, and the performance time varies. It is not because of the network request that the data is taken by the child thread and has nothing to do with the UI thread. I'm not happy with this kind of experience.

A few days have passed, and it's still the same. I'm going to show it to the boss soon. This kind of experience will be scolded ten times.

Is it related to the nesting of ScrollView?

All right, I'll ReFactor the code. No more ScrollView. Directly use a ListView, and then add a headerView to store other content. Because the control package is quite good, did not change how much layout on the OK, a run, smooth and smooth, everything can be easily solved!

It's such a simple question, why do you have to use ScrollView nesting?

Stackoverflow already told you, don't be so nested! Don't be so nested! Don't be so nested! Important things are to be repeated for 3 times.

ListView inside ScrollView is not scrolling on Android

(http://stackoverflow.com/questions/6210895/listview-inside-scrollview-is-not-scrolling-on-android)

Of course, a new API support for embedded sliding has been provided since android 5.0Lollipop, so that requirements like this can be easily implemented.

Here is a website that you are interested to know for yourself. we will not discuss it here.

Android NestedScrolling actual combat

(http://www.race604.com/android-nested-scrolling/)

7. SetText (null) of EmojiconTextView

This is the enhanced version of TextView in the open source emoji library com.rockerhieu.emojicon. I believe many people have used this open source toolkit. TextView has no problem using setText (null). But after EmojiconTextView setText (null), it is tragic. Direct crash shows null pointer. At first I suspected that the view was not initialized, but it wasn't. Then debug it.

Override public void setText (CharSequence text, BufferType type) {SpannableStringBuilder builder = new SpannableStringBuilder (text); EmojiconHandler.addEmojis (getContext (), builder, mEmojiconSize); super.setText (builder, type);}

There seems to be nothing wrong with setText in EmojiconTextView. Click SpannableStringBuilder to go in and have a look. The source code originally looks like this:

/ * * Create a new SpannableStringBuilder containing a copy of the * specified text, including its spans if any. * / public SpannableStringBuilder (CharSequence text) {this (text, 0, text.length ();}

Okay. The problem has been found, text.length (). No wonder the pointer is not empty.

Text = text = = null? "": text; SpannableStringBuilder builder = new SpannableStringBuilder (text)

Just add a line of judgment.

8. Cursor.close ()

Generally speaking, the switch of database is not likely to be forgotten, but the use of cursors may not attract much attention, especially the casual use of cursors. For example, if you use ContentResolver and Cursor to query the pictures in an SD card, it is easy to write the following code:

Cursor cursor = contentResolver.query (uri, null, MediaStore.Images.Media.MIME_TYPE + "=? or" + MediaStore.Images.Media.MIME_TYPE + "=?", new String [] {"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED); while (cursor.moveToNext ()) {/ / TODO}

Cursor does not make non-null judgments, and often does not pay attention to the possibility of an exception thrown when closing cursors.

In the past, in the project, it often occurred that other problems occurred because the cursor was not closed in time or the closure exception was not handled properly, and the problem looked very weird and difficult to solve. Later, I refactored the use of cursors throughout the project, and there has been no similar problem since.

The principle is simple. All Cursor statements are as follows:

Cursor cursor = null

And put it outside the try-catch; if you need to use cursor, make a non-empty judgment first. Then use a utility class to handle the closure of the cursor in the method.

/ * * @ author Leo * * Created in 2015-9-15 * / public class IOUtil {private IOUtil () {} public static void closeQuietly (Closeable closeable) {if (closeable! = null) {try {closeable.close () } catch (Throwable e) {} public static void closeQuietly (Cursor cursor) {if (cursor! = null) {try {cursor.close ();} catch (Throwable e) {}}

I don't think it's necessary to try-catch-finally everywhere.

9 、 java.lang.String cannot be converted to JSONObject

This exception was thrown when parsing the JSON string returned by the server. Debugging did not find any problems, it seems to be a normal JSON format. It turns out that it is the JSON string with BOM (Byte Order Mark). The server code is implemented by PHP, and sometimes developers open and save it directly with windows notepad for convenience of modification, introducing problems that are invisible to the human eye. In fact, there is a lot of "ufeff" this thing, the client code filter on the line.

/ in case: Value of type java.lang.String cannot be converted to JSONObject / / Remove the BOM header if (jsonStr! = null) {jsonStr = jsonStr.trim (); if (jsonStr.startsWith ("ufeff")) {jsonStr = jsonStr.substring (1);}}

10 、 Shape round rect too large to be rendered into a texture

Is the round rectangle too big?

At first I found that a scrollView in acitivity slides around without actually nesting any list controls such as ListView, GridView, but contains nothing more than TextView, ImagView, and so on. Take a look at the log output in Eclipse and find that this warn-level prompt appears. Did I nest this circular rectangle in the outer layer? I have used it in many places, why is there something wrong with this interface?

It was later found that the round rectangle contained so much content that it exceeded the height of the phone and could slide for several pages.

Someone on StackOverFlow said: The easiest solution is to get rid of the rounded corners. If you remove the rounded corners and use a simple rectangle, the hardware renderer will no longer create a single large texture for the background layer, and won't run into the texture size limit any more.

There is also a suggestion: to draw onto the canvas.

Specific link: How Do Solve Shape round rect too large to be rendered into a texture

(http://stackoverflow.com/questions/14519025/how-do-solve-shape-round-rect-too-large-to-be-rendered-into-a-texture-in-android)

I tried the custom control LinearLayout and draw through canvas, but I couldn't solve it. It is possible to remove the radius attribute, but what if I want to keep it?

Another workaround is to disable hardware acceleration in androidManifest.xml, which I only disable in this activity in order to control granularity.

The above are the pitfalls and tips of Android development, and the editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report