Android listview item click to expand
Is it really a headache for projects recently? Previously, I wanted to use ListViewAnnotation to achieve a sliding deletion effect similar to the android notification bar. It seems like a Daniel wrote it by himself. I would like to pay tribute to him first. However, in other words, the implementation principle is also easy to understand, that is, to detect your sliding distance and speed, and then make judgments and operations. For details, refer to the two list modes of Google keep to understand the operation class.
Unfortunately, fragment and biewpager were used in the layout, which resulted in a gesture conflict. For this reason, I changed the gesture operation Detection Method in the library and finally barely changed it. But !!!! The effect was really terrible, so I had to stop it. Finally, I thought about it. I decided to use listview item and click to expand to achieve the desired effect.
Well, after talking a lot of nonsense, we finally have to get started.
First, add three points:
First:
GetLayoutParams () method and setLayoutParams () usage first, we use getLayoutParams () to obtain the LayoutParams of the specified control. Example: LinearLayout. layoutParams lp = (RelativeLayout. layoutParams) deletButton. getLayoutParams (); then, we can set the layoutparams attribute for deleteButton, for example, lp. width = btnWidth; lp. leftMargin = 10; finally, we set the set layoutparams attribute to the specified control: deletButton. setLayoutParams (lp );
Second point:
Public final int getMeasuredHeight () Added in API level 1 Like getMeasuredHeightAndState (), but only returns the raw width component (that is the result is masked by MEASURED_SIZE_MASK ). returnsThe raw measured height of this view. public final int getHeight () Added in API level 1 Return the height of your view. returnsThe height of your view, in pixels. getMeasuredHeight () returns the original measurement height, regardless of the screen. getHeight () returns Is the height displayed on the screen. In fact, when the screen can wrap the content, their values are equal. Only when the view exceeds the screen can the difference be seen. When the screen is exceeded, getMeasuredHeight () equals to getHeight () plus the height not displayed outside the screen.
Third point:
Use of MeasureSpec. MeasureSpec usually appears in a custom View, because in a custom view, we often need to override this method to specify the size of the custom control on the screen. Protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) the two parameters passed in by onMeasure are the size passed in by the control on the previous layer. In many cases, you need to calculate the actual size of the control when rewriting this method, call setMeasuredDimension (int, int) to set the actual size. The widthMeasureSpec and heightMeasureSpec passed in onMeasure are not general dimensional values, but values that combine the mode and size. We need to use int mode = MeasureSpec. getMode (widthMeasureSpec) to get the mode, and use int size = MeasureSpec. getSize (widthMeasureSpec) to get the size. There are three modes: MeasureSpec. UNSPECIFIED, MeasureSpec. EXACTLY, and MeasureSpec. AT_MOST. MeasureSpec. EXACTLY is the exact size. When we specify the layout_width or layout_height of the control as a specific value, for example, andorid: layout_width = "50dip" or FILL_PARENT, the control size is determined, all are precise dimensions. MeasureSpec. AT_MOST is the maximum size. When the layout_width or layout_height of the control is set to WRAP_CONTENT, the control Size usually changes with the control's sub-spaces or content, in this case, the widget size must not exceed the maximum size allowed by the parent widget. Therefore, the mode is AT_MOST, and size provides the maximum size allowed by the parent control. MeasureSpec. UNSPECIFIED is an UNSPECIFIED size. In this case, the parent control is generally AdapterView, which is passed in through the measure method. Then, we can call MeasureSpec. makeMeasureSpec (int size, int mode) to set it.
Now, let's go to the demo. You can expand it on your own.
Haha, the effect is okay. That, the icon is a little cute, please do not laugh (self-drawn, hard to force a programmer ).
Okay. Next, let's take a look at the implementation of dynamic effects. Of course, first go to the source code.
Package wenyue. expandlistview. me; import android. util. log; import android. view. view; import android. view. animation. animation; import android. view. animation. transformation; import android. widget. linearLayout. layoutParams;/*** animation * November 18, 2014 * wolf asked month * canglangwenyue. github. io * @ author canglangwenyue **/public class ViewExpandAnimation extends Animation {private View mAnimationView = null; priva Te LayoutParams mViewLayoutParams = null; private int mStart = 0; private int mEnd = 0; public ViewExpandAnimation (View view) {animationSettings (view, 500);} public ViewExpandAnimation (View view, int duration) {animationSettings (view, duration);} private void animationSettings (View view, int duration) {setDuration (duration); mAnimationView = view; mViewLayoutParams = (LayoutParams) view. getLayoutParams (); MStart = mViewLayoutParams. bottomMargin; mEnd = (mStart = 0? (0-view. getHeight (): 0); view. setVisibility (View. VISIBLE) ;}@ Overrideprotected void applyTransformation (float interpolatedTime, Transformation t) {super. applyTransformation (interpolatedTime, t); if (interpolatedTime <1.0f) {mViewLayoutParams. bottomMargin = mStart + (int) (mEnd-mStart) * interpolatedTime); // invalidate mAnimationView. requestLayout ();} else {mViewLayoutParams. bottomMargin = MEnd; mAnimationView. requestLayout (); if (mEnd! = 0) {mAnimationView. setVisibility (View. GONE) ;}} Log. I ("hehe", "interpolatedTime =" + interpolatedTime + ", bottomMargin" + mViewLayoutParams. bottomMargin) ;}} there are not many real-time code, and setDuration (duration) sets the animation duration. Then call RelitaveLayout. bottomMargin; The developer document for this attribute is interpreted as the bottom margin in pixels of The child. mAnimationView. requestLayout (); this method calls the Object. layout (...) method to relay the layout.
As for listview adapter rewriting, it is relatively simple. Therefore, we will not post all source code. Let's just talk about what you need to pay attention.
First, you need (...) To load the item layout file of the custom listview:
convertView = myInflater.inflate(R.layout.expand_item, null);
Next, paste the corresponding layout file code:
By default, the content of the second RelativeLayout layout file in the nested layout of activity onStart is hidden.
The settings in BaseAdapter are as follows:
RelativeLayout footer = (RelativeLayout) convertView .findViewById(R.id.footer); int widthSpec = MeasureSpec.makeMeasureSpec( (int) (mLcdWidth - 10 * mDensity), MeasureSpec.EXACTLY); footer.measure(widthSpec, 0); LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) footer .getLayoutParams(); params.bottomMargin = -footer.getMeasuredHeight(); footer.setVisibility(View.GONE);
Then, set the setOnItemClickListener method in the onCreate method, click item in it, and start the animation. Click again to hide it, and only one item can be expanded at a time (because I personally think it is impossible for the user to operate the hidden operations of two items at the same time). The Code is as follows:
if (mLastTouchTag != null) { View temp = arg0.findViewWithTag(mLastTouchTag); if (temp != null) { View footTemp = temp.findViewById(R.id.footer); if (footTemp != null && (footTemp.getVisibility() != View.GONE)) { footTemp.startAnimation(new ViewExpandAnimation( footTemp)); } } } mLastTouchTag = (ViewHolder) v.getTag(); // onion555 end View footer = v.findViewById(R.id.footer); footer.startAnimation(new ViewExpandAnimation(footer));
Okay. Write it here. If you have any questions, leave a message. Similarly, add the source code at the end.
Click Open Link