Keywords: Android TextView
github:https://github.com/Manabu-GT/ExpandableTextView
本篇主講ExpandableTextView庫,這個開源項目主要用于Item顯示文字內(nèi)容過多,采用點擊圖標(biāo)展開收縮的方式來顯示。
效果圖
個人實現(xiàn)思路
投根據(jù)伸縮狀態(tài),方向箭控制src變化或者動畫旋轉(zhuǎn)
投根據(jù)伸縮狀態(tài),文字內(nèi)容改變maxLength或者動態(tài)改變控件高度
以上僅為個人猜想,博主還是的看過源碼才能清楚具體實現(xiàn).在看過源碼后決定在本篇博客補充一個知識點(了解的自動忽略)
onFinishInflate
1.Activity onCreate(Bundle savedInstanceState)和onFinishInflate(),onCreate是activity的創(chuàng)建回調(diào),一般我們會把setContentView(R.layout.activity_main)放在oncreate方法里面,這個方法主要是將xml布局文件里的控件映射到activity里面。 而View首先會執(zhí)行構(gòu)造方法,然后會回調(diào)onFinishInflate()方法來完成初始化。所以 onFinishInflate() 回調(diào)方法是從XML加載該組件并用它構(gòu)建界面之后調(diào)用的方法。
ExpandableTextView從它構(gòu)造函數(shù)僅發(fā)現(xiàn)了解析自定義屬性的基本操作,而后在onFinishInflate函數(shù)發(fā)現(xiàn)有findviewbyid的操作,用于初始化LinearLayout的字控件,并綁定控件點擊事件。
onClick方法主要做了三件事:狀態(tài)存儲drawable變化、動畫
@Override
public void onClick(View view) {
if (mButton.getVisibility() != View.VISIBLE) {
return;
}
mCollapsed = !mCollapsed;
mButton.setImageDrawable(mCollapsed ? mExpandDrawable : mCollapseDrawable);
if (mCollapsedStatus != null) {
mCollapsedStatus.put(mPosition, mCollapsed);
}
// mark that the animation is in progress
mAnimating = true;
Animation animation;
if (mCollapsed) {
animation = new ExpandCollapseAnimation(this, getHeight(), mCollapsedHeight);
} else {
animation = new ExpandCollapseAnimation(this, getHeight(), getHeight() +
mTextHeightWithMaxLines - mTv.getHeight());
}
animation.setFillAfter(true);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
applyAlphaAnimation(mTv, mAnimAlphaStart);
}
@Override
public void onAnimationEnd(Animation animation) {
// clear animation here to avoid repeated applyTransformation() calls
clearAnimation();
// clear the animation flag
mAnimating = false;
// notify the listener
if (mListener != null) {
mListener.onExpandStateChanged(mTv, !mCollapsed);
}
}
@Override
public void onAnimationRepeat(Animation animation) { }
});
clearAnimation();
startAnimation(animation);
}
動畫結(jié)束了通過OnExpandStateChangeListener回調(diào)出來供我們自己處理,而applyAlphaAnimation方法僅是一個兼容api不同版本的透明動畫
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static void applyAlphaAnimation(View view, float alpha) {
if (isPostHoneycomb()) {
view.setAlpha(alpha);
} else {
AlphaAnimation alphaAnimation = new AlphaAnimation(alpha, alpha);
// make it instant
alphaAnimation.setDuration(0);
alphaAnimation.setFillAfter(true);
view.startAnimation(alphaAnimation);
}
}
ExpandCollapseAnimation內(nèi)部類真正動畫的具體實現(xiàn)代碼,通過動態(tài)改變weight、height屬性重繪實現(xiàn)。
class ExpandCollapseAnimation extends Animation {
//..................................略.............................................
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final int newHeight = (int)((mEndHeight - mStartHeight) * interpolatedTime + mStartHeight);
mTv.setMaxHeight(newHeight - mMarginBetweenTxtAndBottom);
if (Float.compare(mAnimAlphaStart, 1.0f) != 0) {
applyAlphaAnimation(mTv, mAnimAlphaStart + interpolatedTime * (1.0f - mAnimAlphaStart));
}
mTargetView.getLayoutParams().height = newHeight;
mTargetView.requestLayout();
}
@Override
public boolean willChangeBounds( ) {
return true;
}
}
關(guān)于透明動畫,如果你運行官方demo可能你肉眼無法看出來,默認(rèn)duration是在太短,可以通過自定義屬性ExpandableTextView_animDuration自己體驗一下。
/* The default animation duration */
private static final int DEFAULT_ANIM_DURATION = 300;
由于該開源項目是很久以前的,于是乎發(fā)現(xiàn)了一點可以優(yōu)化拓展的知識點:Compat系列
這個開源項目里的getDrawable方法目前可以完全不用自己再造輪子了,Compat系列的ContextCompat已有這個方法。
諸如此類的方法Compat系列類還有很多需要自己去挖掘。
目前android兼容6.0的動態(tài)權(quán)限很多流行庫也都有用到Compat系列類,如果你還有懷疑可以看看ContextCompat.checkSelfPermission()我就不一一列舉,蘿卜青菜各有所愛,我喜歡所以我推薦。
至于onMeasure函數(shù)的設(shè)置maxLength 、mCollapsedHeight計算有興趣的可以看看比較簡單。
idea雜談
android大環(huán)境下有點不景氣,上千人面一個崗位(虛假簡歷實在太多,21-22歲的剛出社會的學(xué)生都聲稱自己3年經(jīng)驗),都在群里不斷抱怨工作不好找,要回家搬磚去了??!
樓主認(rèn)為你有時間在這里抱怨還不如去好好提升自己能力,提高個人技能,增加面試拿offer成功率。
機會是留給準(zhǔn)備好的人,抓緊時間充實自己,提升自我能力,管別人作甚??!用小說里看到的一句話來送給大伙兒共勉:在絕對的實力面前,一切的陰謀詭計都是土崩瓦狗