Typeface add @font/xxx support for fontconfig's fonts

This commit is contained in:
houzh 2023-08-02 08:52:44 +08:00
parent 40c2ff895f
commit 100ff76121
5 changed files with 97 additions and 51 deletions

View File

@ -604,7 +604,7 @@ void Layout::drawText(Canvas&canvas,int firstLine,int lastLine){
case ALIGN_OPPOSITE: case ALIGN_OPPOSITE:
case ALIGN_RIGHT : x = mWidth-lw ; break; case ALIGN_RIGHT : x = mWidth-lw ; break;
} }
LOGV("line[%d] xy=%d,%d mWidth=%d [%s](%d)'s TextWidth=%d fontsize=%.f alignment=%x abearing=%f", LOGV("line[%d](%d,%d) layoutWidth=%d [%s](%d).width=%d fontsize=%.f alignment=%x abearing=%f",
lineNum,x,y,mWidth,TextUtils::unicode2utf8(line).c_str(),line.size(),lw,mFontSize,mAlignment,te.x_bearing); lineNum,x,y,mWidth,TextUtils::unicode2utf8(line).c_str(),line.size(),lw,mFontSize,mAlignment,te.x_bearing);
canvas.move_to(x - te.x_bearing,y); canvas.move_to(x - te.x_bearing,y);
canvas.show_text(processBidi(line)); canvas.show_text(processBidi(line));

View File

@ -302,6 +302,12 @@ int Typeface::loadFromPath(const std::string&path) {
return sSystemFontMap.size(); return sSystemFontMap.size();
} }
#ifdef _WIN32
#define PATH_SEPARATOR "\\"
#else
#define PATH_SEPARATOR "/"
#endif
int Typeface::loadFromFontConfig() { int Typeface::loadFromFontConfig() {
FcConfig *config = FcInitLoadConfigAndFonts (); FcConfig *config = FcInitLoadConfigAndFonts ();
if(!config) return false; if(!config) return false;
@ -327,8 +333,19 @@ int Typeface::loadFromFontConfig() {
for (int i=0; fs && i < fs->nfont; i++) { for (int i=0; fs && i < fs->nfont; i++) {
FcPattern *pat = fs->fonts[i];//FcPatternDuplicate(fs->fonts[i]); FcPattern *pat = fs->fonts[i];//FcPatternDuplicate(fs->fonts[i]);
Typeface *tf = new Typeface(*pat,""); Typeface *tf = new Typeface(*pat,"");
FcChar8* fontFile = nullptr;
const std::string family = tf->getFamily(); const std::string family = tf->getFamily();
if(FcPatternGetString(pat, FC_FILE, 0, &fontFile) == FcResultMatch){
std::string font((char*)fontFile);
size_t pos = font.find_last_of(".");
if(pos!=std::string::npos)
font = font.substr(0,pos);
pos = font.find_last_of(PATH_SEPARATOR);
if(pos!=std::string::npos)
font = font.substr(pos+1);
LOGD("filename=%s/%s family=%s",fontFile,font.c_str(),family.c_str());
sSystemFontMap.insert({font,tf});
}
sSystemFontMap.insert({family,tf}); sSystemFontMap.insert({family,tf});
LOGV("font %s %p",family.c_str(),tf); LOGV("font %s %p",family.c_str(),tf);
if(std::regex_search(family,patSans)) { if(std::regex_search(family,patSans)) {

View File

@ -80,11 +80,11 @@ void AbsListView::initAbsListView(const AttributeSet&atts) {
mLayoutMode = LAYOUT_NORMAL; mLayoutMode = LAYOUT_NORMAL;
mActivePointerId = INVALID_POINTER; mActivePointerId = INVALID_POINTER;
mTranscriptMode=TRANSCRIPT_MODE_DISABLED; mTranscriptMode=TRANSCRIPT_MODE_DISABLED;
mRecycler=new RecycleBin(this); mRecycler = new RecycleBin(this);
mScrollUp = mScrollDown = nullptr; mScrollUp = mScrollDown = nullptr;
mCachingStarted = mCachingActive =false; mCachingStarted = mCachingActive =false;
mIsScrap[0]=mIsScrap[1]=0; mIsScrap[0] = mIsScrap[1] = 0;
mDensityScale=getContext()->getDisplayMetrics().density; mDensityScale = getContext()->getDisplayMetrics().density;
mDrawSelectorOnTop = atts.getBoolean("drawSelectorOnTop",false); mDrawSelectorOnTop = atts.getBoolean("drawSelectorOnTop",false);
setStackFromBottom(atts.getBoolean("stackFromBottom",false)); setStackFromBottom(atts.getBoolean("stackFromBottom",false));
@ -811,7 +811,8 @@ std::vector<int>AbsListView::getDrawableStateForSelector() {
// The selector uses this View's drawable state. The selected child view // The selector uses this View's drawable state. The selected child view
// is disabled, so we need to remove the enabled state from the drawable states. // is disabled, so we need to remove the enabled state from the drawable states.
int enabledState = -1;//ENABLED_STATE_SET[0]; const std::vector<int>enableState = StateSet::get(StateSet::VIEW_STATE_ENABLED);
int enabledState = enableState[0];//-1;//ENABLED_STATE_SET[0];
// If we don't have any extra space, it will return one of the static // If we don't have any extra space, it will return one of the static
// state arrays, and clearing the enabled state on those arrays is a // state arrays, and clearing the enabled state on those arrays is a
@ -925,17 +926,17 @@ void AbsListView::confirmCheckedPositionsById() {
bool checkedCountChanged = false; bool checkedCountChanged = false;
for (int checkedIndex = 0; checkedIndex < mCheckedIdStates.size(); checkedIndex++) { for (int checkedIndex = 0; checkedIndex < mCheckedIdStates.size(); checkedIndex++) {
long id = mCheckedIdStates.keyAt(checkedIndex); const long id = mCheckedIdStates.keyAt(checkedIndex);
int lastPos = mCheckedIdStates.valueAt(checkedIndex); const int lastPos = mCheckedIdStates.valueAt(checkedIndex);
long lastPosId = mAdapter->getItemId(lastPos); const long lastPosId = mAdapter->getItemId(lastPos);
if (id != lastPosId) { if (id != lastPosId) {
// Look around to see if the ID is nearby. If not, uncheck it. // Look around to see if the ID is nearby. If not, uncheck it.
int start = std::max(0, lastPos - CHECK_POSITION_SEARCH_DISTANCE); const int start = std::max(0, lastPos - CHECK_POSITION_SEARCH_DISTANCE);
int end = std::min(lastPos + CHECK_POSITION_SEARCH_DISTANCE, mItemCount); const int end = std::min(lastPos + CHECK_POSITION_SEARCH_DISTANCE, mItemCount);
bool found = false; bool found = false;
for (int searchPos = start; searchPos < end; searchPos++) { for (int searchPos = start; searchPos < end; searchPos++) {
long searchId = mAdapter->getItemId(searchPos); const long searchId = mAdapter->getItemId(searchPos);
if (id == searchId) { if (id == searchId) {
found = true; found = true;
mCheckStates.put(searchPos, true); mCheckStates.put(searchPos, true);
@ -1492,7 +1493,7 @@ bool AbsListView::canScrollDown()const {
// ... Or bottom of the last element is not visible // ... Or bottom of the last element is not visible
if (!canScrollDown && count > 0) { if (!canScrollDown && count > 0) {
View* child = getChildAt(count - 1); View* child = getChildAt(count - 1);
canScrollDown = child->getBottom() > getBottom() - mListPadding.bottom(); canScrollDown = child->getBottom() > getBottom() - mListPadding.height;
} }
return canScrollDown; return canScrollDown;
@ -1511,7 +1512,7 @@ bool AbsListView::canScrollList(int direction) {
if (direction > 0) { if (direction > 0) {
const int lastBottom = getChildAt(childCount - 1)->getBottom(); const int lastBottom = getChildAt(childCount - 1)->getBottom();
const int lastPosition = firstPosition + childCount; const int lastPosition = firstPosition + childCount;
return lastPosition < mItemCount || lastBottom > getHeight() - listPadding.height;//bottom; return lastPosition < mItemCount || lastBottom > getHeight() - listPadding.height;
} else { } else {
const int firstTop = getChildAt(0)->getTop(); const int firstTop = getChildAt(0)->getTop();
return firstPosition > 0 || firstTop < listPadding.top; return firstPosition > 0 || firstTop < listPadding.top;
@ -1536,7 +1537,7 @@ bool AbsListView::trackMotionScroll(int deltaY, int incrementalDeltaY) {
int effectivePaddingBottom = 0; int effectivePaddingBottom = 0;
if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
effectivePaddingTop = listPadding.top; effectivePaddingTop = listPadding.top;
effectivePaddingBottom = listPadding.bottom(); effectivePaddingBottom = listPadding.height;
} }
// FIXME account for grid vertical spacing too? // FIXME account for grid vertical spacing too?
@ -1566,7 +1567,7 @@ bool AbsListView::trackMotionScroll(int deltaY, int incrementalDeltaY) {
mFirstPositionDistanceGuess += incrementalDeltaY; mFirstPositionDistanceGuess += incrementalDeltaY;
} }
if (firstPosition + childCount == mItemCount) { if (firstPosition + childCount == mItemCount) {
mLastPositionDistanceGuess = lastBottom + listPadding.bottom(); mLastPositionDistanceGuess = lastBottom + listPadding.height;
} else { } else {
mLastPositionDistanceGuess += incrementalDeltaY; mLastPositionDistanceGuess += incrementalDeltaY;
} }
@ -1574,7 +1575,7 @@ bool AbsListView::trackMotionScroll(int deltaY, int incrementalDeltaY) {
bool cannotScrollDown = (firstPosition == 0 && bool cannotScrollDown = (firstPosition == 0 &&
firstTop >= listPadding.top && incrementalDeltaY >= 0); firstTop >= listPadding.top && incrementalDeltaY >= 0);
bool cannotScrollUp = (firstPosition + childCount == mItemCount && bool cannotScrollUp = (firstPosition + childCount == mItemCount &&
lastBottom <= getHeight() - listPadding.bottom() && incrementalDeltaY <= 0); lastBottom <= getHeight() - listPadding.height && incrementalDeltaY <= 0);
if (cannotScrollDown || cannotScrollUp) { if (cannotScrollDown || cannotScrollUp) {
return incrementalDeltaY != 0; return incrementalDeltaY != 0;
} }
@ -1615,7 +1616,7 @@ bool AbsListView::trackMotionScroll(int deltaY, int incrementalDeltaY) {
} else { } else {
int bottom = getHeight() - incrementalDeltaY; int bottom = getHeight() - incrementalDeltaY;
if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
bottom -= listPadding.bottom(); bottom -= listPadding.height;
} }
for (int i = childCount - 1; i >= 0; i--) { for (int i = childCount - 1; i >= 0; i--) {
View* child = getChildAt(i); View* child = getChildAt(i);
@ -1792,7 +1793,7 @@ void AbsListView::onDetachedFromWindow() {
mIsDetaching = false; mIsDetaching = false;
} }
void AbsListView::onWindowFocusChanged(bool hasWindowFocus){ void AbsListView::onWindowFocusChanged(bool hasWindowFocus) {
AdapterView::onWindowFocusChanged(hasWindowFocus); AdapterView::onWindowFocusChanged(hasWindowFocus);
int touchMode = isInTouchMode() ? TOUCH_MODE_ON : TOUCH_MODE_OFF; int touchMode = isInTouchMode() ? TOUCH_MODE_ON : TOUCH_MODE_OFF;
@ -2008,7 +2009,7 @@ void AbsListView::dispatchDrawableHotspotChanged(float x, float y) {
int AbsListView::pointToPosition(int x, int y) { int AbsListView::pointToPosition(int x, int y) {
Rect frame; Rect frame;
int count = getChildCount(); const int count = getChildCount();
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--) {
View* child = getChildAt(i); View* child = getChildAt(i);
if (child->getVisibility() == View::VISIBLE) { if (child->getVisibility() == View::VISIBLE) {
@ -2154,8 +2155,7 @@ void AbsListView::onTouchModeChanged(bool isInTouchMode) {
} }
updateSelectorState(); updateSelectorState();
} else { } else {
int touchMode = mTouchMode; if (mTouchMode == TOUCH_MODE_OVERSCROLL || mTouchMode == TOUCH_MODE_OVERFLING) {
if (touchMode == TOUCH_MODE_OVERSCROLL || touchMode == TOUCH_MODE_OVERFLING) {
mFlingRunnable.endFling(); mFlingRunnable.endFling();
if (mPositionScroller)mPositionScroller->stop(); if (mPositionScroller)mPositionScroller->stop();
@ -2223,22 +2223,20 @@ bool AbsListView::onTouchEvent(MotionEvent& ev) {
} }
case MotionEvent::ACTION_POINTER_DOWN: { case MotionEvent::ACTION_POINTER_DOWN: {
// New pointers take over dragging duties // New pointers take over dragging duties
int index = ev.getActionIndex(); const int index = ev.getActionIndex();
int id = ev.getPointerId(index); const int id = ev.getPointerId(index);
int x = (int) ev.getX(index);
int y = (int) ev.getY(index);
mMotionCorrection = 0; mMotionCorrection = 0;
mActivePointerId = id; mActivePointerId = id;
mMotionX = x; mMotionX = ev.getX(index);
mMotionY = y; mMotionY = ev.getY(index);
int motionPosition = pointToPosition(x, y); int motionPosition = pointToPosition(mMotionX, mMotionY);
if (motionPosition >= 0) { if (motionPosition >= 0) {
// Remember where the motion event started // Remember where the motion event started
View* child = getChildAt(motionPosition - mFirstPosition); View* child = getChildAt(motionPosition - mFirstPosition);
mMotionViewOriginalTop = child->getTop(); mMotionViewOriginalTop = child->getTop();
mMotionPosition = motionPosition; mMotionPosition = motionPosition;
} }
mLastY = y; mLastY = mMotionY;
break; break;
} }
} }
@ -2646,7 +2644,7 @@ void AbsListView::onTouchMove(MotionEvent&ev, MotionEvent&vtev) {
case TOUCH_MODE_DONE_WAITING:/*2*/ case TOUCH_MODE_DONE_WAITING:/*2*/
// Check if we have moved far enough that it looks more like a // Check if we have moved far enough that it looks more like a
// scroll than a tap. If so, we'll enter scrolling mode. // scroll than a tap. If so, we'll enter scrolling mode.
if (startScrollIfNeeded((int) ev.getX(pointerIndex), y, &vtev)) { if (startScrollIfNeeded(x, y, &vtev)) {
break; break;
} }
// Otherwise, check containment within list bounds. If we're // Otherwise, check containment within list bounds. If we're
@ -2668,7 +2666,7 @@ void AbsListView::onTouchMove(MotionEvent&ev, MotionEvent&vtev) {
break; break;
case TOUCH_MODE_SCROLL:/*3*/ case TOUCH_MODE_SCROLL:/*3*/
case TOUCH_MODE_OVERSCROLL:/*5*/ case TOUCH_MODE_OVERSCROLL:/*5*/
scrollIfNeeded((int) ev.getX(pointerIndex), y, &vtev); scrollIfNeeded(x, y, &vtev);
break; break;
} }
} }
@ -2726,7 +2724,8 @@ void AbsListView::onTouchUp(MotionEvent&ev) {
child->setPressed(false); child->setPressed(false);
} }
float x = ev.getX(); const float x = ev.getX();
const float y = ev.getY();
bool inList = x > mListPadding.left && x < getWidth() - mListPadding.width; bool inList = x > mListPadding.left && x < getWidth() - mListPadding.width;
if (inList && !child->hasExplicitFocusable()) { if (inList && !child->hasExplicitFocusable()) {
mPerformClick.mClickMotionPosition = mMotionPosition; mPerformClick.mClickMotionPosition = mMotionPosition;
@ -2749,7 +2748,7 @@ void AbsListView::onTouchUp(MotionEvent&ev) {
if (d && dynamic_cast<TransitionDrawable*>(d)) { if (d && dynamic_cast<TransitionDrawable*>(d)) {
((TransitionDrawable*) d)->resetTransition(); ((TransitionDrawable*) d)->resetTransition();
} }
mSelector->setHotspot(x, ev.getY()); mSelector->setHotspot(x, y);
} }
if (mTouchModeReset != nullptr) { if (mTouchModeReset != nullptr) {
removeCallbacks(mTouchModeReset); removeCallbacks(mTouchModeReset);
@ -2831,7 +2830,7 @@ void AbsListView::onTouchUp(MotionEvent&ev) {
case TOUCH_MODE_OVERSCROLL:/*5*/ case TOUCH_MODE_OVERSCROLL:/*5*/
mVelocityTracker->computeCurrentVelocity(1000, mMaximumVelocity); mVelocityTracker->computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) mVelocityTracker->getYVelocity(mActivePointerId); const int initialVelocity = (int) mVelocityTracker->getYVelocity(mActivePointerId);
reportScrollStateChange(OnScrollListener::SCROLL_STATE_FLING); reportScrollStateChange(OnScrollListener::SCROLL_STATE_FLING);
if (std::abs(initialVelocity) > mMinimumVelocity) { if (std::abs(initialVelocity) > mMinimumVelocity) {
@ -3272,12 +3271,13 @@ void AbsListView::PositionScroller::stop() {
} }
void AbsListView::PositionScroller::operator()() {//todo for horizontal void AbsListView::PositionScroller::operator()() {//todo for horizontal
int listHeight = mLV->getHeight(); const int listHeight = mLV->getHeight();
int firstPos = mLV->mFirstPosition; const int firstPos = mLV->mFirstPosition;
const int childCount = mLV->getChildCount();
switch (mMode) { switch (mMode) {
case MOVE_DOWN_POS: { case MOVE_DOWN_POS: {
int lastViewIndex = mLV->getChildCount() - 1; const int lastViewIndex = childCount - 1;
int lastPos = firstPos + lastViewIndex; const int lastPos = firstPos + lastViewIndex;
if (lastViewIndex < 0) { if (lastViewIndex < 0) {
return; return;
@ -3293,8 +3293,8 @@ void AbsListView::PositionScroller::operator()() {//todo for horizontal
int lastViewHeight = lastView->getHeight(); int lastViewHeight = lastView->getHeight();
int lastViewTop = lastView->getTop(); int lastViewTop = lastView->getTop();
int lastViewPixelsShowing = listHeight - lastViewTop; int lastViewPixelsShowing = listHeight - lastViewTop;
int extraScroll = lastPos < mLV->mItemCount - 1 ? int extraScroll = lastPos < childCount - 1 ?
std::max(mLV->mListPadding.bottom(), mExtraScroll) : mLV->mListPadding.bottom(); std::max(mLV->mListPadding.height, mExtraScroll) : mLV->mListPadding.height;
int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll; int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
mLV->smoothScrollBy(scrollBy, mScrollDuration, true, lastPos < mTargetPos); mLV->smoothScrollBy(scrollBy, mScrollDuration, true, lastPos < mTargetPos);
@ -3308,7 +3308,6 @@ void AbsListView::PositionScroller::operator()() {//todo for horizontal
case MOVE_DOWN_BOUND: { case MOVE_DOWN_BOUND: {
int nextViewIndex = 1; int nextViewIndex = 1;
int childCount = mLV->getChildCount();
if (firstPos == mBoundPos || childCount <= nextViewIndex if (firstPos == mBoundPos || childCount <= nextViewIndex
|| firstPos + childCount >= mLV->mItemCount) { || firstPos + childCount >= mLV->mItemCount) {
@ -3326,7 +3325,7 @@ void AbsListView::PositionScroller::operator()() {//todo for horizontal
View* nextView = mLV->getChildAt(nextViewIndex); View* nextView = mLV->getChildAt(nextViewIndex);
int nextViewHeight = nextView->getHeight(); int nextViewHeight = nextView->getHeight();
int nextViewTop = nextView->getTop(); int nextViewTop = nextView->getTop();
int extraScroll = std::max(mLV->mListPadding.bottom(), mExtraScroll); int extraScroll = std::max(mLV->mListPadding.height, mExtraScroll);
if (nextPos < mBoundPos) { if (nextPos < mBoundPos) {
mLV->smoothScrollBy(std::max(0, nextViewHeight + nextViewTop - extraScroll), mLV->smoothScrollBy(std::max(0, nextViewHeight + nextViewTop - extraScroll),
mScrollDuration, true, true); mScrollDuration, true, true);
@ -3371,11 +3370,11 @@ void AbsListView::PositionScroller::operator()() {//todo for horizontal
} }
case MOVE_UP_BOUND: { case MOVE_UP_BOUND: {
int lastViewIndex = mLV->getChildCount() - 2; const int lastViewIndex = childCount - 2;
if (lastViewIndex < 0) { if (lastViewIndex < 0) {
return; return;
} }
int lastPos = firstPos + lastViewIndex; const int lastPos = firstPos + lastViewIndex;
if (lastPos == mLastSeenPos) { if (lastPos == mLastSeenPos) {
// No new views, let things keep going. // No new views, let things keep going.
@ -3413,7 +3412,6 @@ void AbsListView::PositionScroller::operator()() {//todo for horizontal
mLastSeenPos = firstPos; mLastSeenPos = firstPos;
int childCount = mLV->getChildCount();
int position = mTargetPos; int position = mTargetPos;
int lastPos = firstPos + childCount - 1; int lastPos = firstPos + childCount - 1;
@ -3658,7 +3656,6 @@ void AbsListView::FlingRunnable::start(int initialVelocity) {
mLV->mFlingProfilingStarted = true; mLV->mFlingProfilingStarted = true;
} }
} }
/*if (mFlingStrictSpan == nullptr) { /*if (mFlingStrictSpan == nullptr) {
mFlingStrictSpan = StrictMode.enterCriticalSpan("AbsListView-fling"); mFlingStrictSpan = StrictMode.enterCriticalSpan("AbsListView-fling");
}*/ }*/

View File

@ -82,7 +82,7 @@ void ListView::adjustViewsUpOrDown() {
} else { } else {
// we are too high, slide all views down to align with bottom // we are too high, slide all views down to align with bottom
child = getChildAt(childCount - 1); child = getChildAt(childCount - 1);
delta = child->getBottom() - (getHeight() - mListPadding.height);//bottom); delta = child->getBottom() - (getHeight() - mListPadding.height);
if (mFirstPosition + childCount < mItemCount) { if (mFirstPosition + childCount < mItemCount) {
// It's OK to have some space below the last item if it is // It's OK to have some space below the last item if it is
@ -548,6 +548,22 @@ View* ListView::moveSelection(View* oldSel, View* newSel, int delta, int childre
int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, selectedPosition); int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, selectedPosition);
int bottomSelectionPixel = getBottomSelectionPixel(childrenTop, fadingEdgeLength, selectedPosition); int bottomSelectionPixel = getBottomSelectionPixel(childrenTop, fadingEdgeLength, selectedPosition);
if (delta > 0) {//Scrolling Down. if (delta > 0) {//Scrolling Down.
/*
* Case 1: Scrolling down.
* Before After
* | | | |
* +-------+ +-------+
* | A | | A |
* | 1 | => +-------+
* +-------+ | B |
* | B | | 2 |
* +-------+ +-------+
* | | | |
*
* Try to keep the top of the previously selected item where it was.
* oldSel = A
* sel = B
*/
// Put oldSel (A) where it belongs // Put oldSel (A) where it belongs
oldSel = makeAndAddView(selectedPosition - 1, oldSel->getTop(), true, mListPadding.left, false); oldSel = makeAndAddView(selectedPosition - 1, oldSel->getTop(), true, mListPadding.left, false);
@ -587,6 +603,23 @@ View* ListView::moveSelection(View* oldSel, View* newSel, int delta, int childre
fillUp(mSelectedPosition - 2, sel->getTop() - dividerHeight); fillUp(mSelectedPosition - 2, sel->getTop() - dividerHeight);
} }
} else if (delta < 0) {//Scrolling up. } else if (delta < 0) {//Scrolling up.
/*
* Case 2: Scrolling up.
* Before After
* | | | |
* +-------+ +-------+
* | A | | A |
* +-------+ => | 1 |
* | B | +-------+
* | 2 | | B |
* +-------+ +-------+
* | | | |
*
* Try to keep the top of the item about to become selected where it was.
* newSel = A
* olSel = B
*/
if (newSel != nullptr) { if (newSel != nullptr) {
// Try to position the top of newSel (A) where it was before it was selected // Try to position the top of newSel (A) where it was before it was selected
sel = makeAndAddView(selectedPosition, newSel->getTop(), true, mListPadding.left,true); sel = makeAndAddView(selectedPosition, newSel->getTop(), true, mListPadding.left,true);
@ -1983,8 +2016,7 @@ void ListView::measureItem(View* child) {
if (lpHeight > 0) { if (lpHeight > 0) {
childHeightSpec = MeasureSpec::makeMeasureSpec(lpHeight, MeasureSpec::EXACTLY); childHeightSpec = MeasureSpec::makeMeasureSpec(lpHeight, MeasureSpec::EXACTLY);
} else { } else {
childHeightSpec = MeasureSpec::makeSafeMeasureSpec(getMeasuredHeight(), childHeightSpec = MeasureSpec::makeSafeMeasureSpec(getMeasuredHeight(),MeasureSpec::UNSPECIFIED);
MeasureSpec::UNSPECIFIED);
} }
child->measure(childWidthSpec, childHeightSpec); child->measure(childWidthSpec, childHeightSpec);
} }

View File

@ -1499,7 +1499,7 @@ void TextView::updateTextColors(){
color = mHintTextColor->getColorForState(drawableState, mHintTextColor->getDefaultColor()); color = mHintTextColor->getColorForState(drawableState, mHintTextColor->getDefaultColor());
if (color != mCurHintTextColor) { if (color != mCurHintTextColor) {
mCurHintTextColor = color; mCurHintTextColor = color;
//if (mText.length() == 0) inval = true; inval = !mLayout->getText().empty();
} }
} }
if (inval) { if (inval) {