2013-07-13 32 views
1

我發現類似的主題已經多次解決,但我無法找到解決方案。

我使用帶自定義CursorAdapter的ListView,它從數據庫獲取數據。這些行是由基於自定義相對佈局的XML文件創建的,該佈局具有作爲背景的圖像,並且應該保持圖像的高寬比。相對佈局的寬度設置爲match_parent,然後根據圖像的高寬比計算高度。

在相對佈局中有5個項目(實際上有6個項目,第6個項目是空白視圖,只是將行分成兩半):1個ImageView和4個自定義文本視圖,它們被修改爲自動調整大小文本取決於TextView的高度(文本的大小設置爲百分比,這裏參數heightPercentage是0.5,所以文本的大小應該是TextView高度的50%)。

一切似乎工作,但有時一些項目不能正確呈現(文本大小似乎是正確的,但TextView的寬度太短。滾動幾個項目後,然後返回一切都很好。

這裏是照片:

正確的(滾動後):
Correct

不正確的一個(前滾動)
Incorrect

編輯: 我試圖使用在互聯網上發現的一些autosize textviews,行爲或多或少相似;有時視圖不能正確渲染,直到滾動ocurrs,或者它首先被正確渲染,但是在滾動後它被搞砸了......在我看來,在我所做的Listview行中使用的自定義視圖有一些特定的規則不明白:-(我試圖把方法像invalidateViews(),notifyDataSetChanged()到代碼的不同位置,有時甚至像runInIOThread(),但沒有成功,行爲永遠不會改變...
帶有自定義自動調整的Android ListView Textview - 有些項目直到滾動才能正常顯示



下面是叫RelativeLayoutKeepRatio自定義相對佈局,稱爲WidthResizeTextView定製的TextView和自定義的CursorAdapter稱爲MyCWGCursorAdapter的代碼。

public class RelativeLayoutKeepRatio extends RelativeLayout { 
private float aspectRatio = 0; 
private ViewGroup.LayoutParams mLayoutParams = null; 

public RelativeLayoutKeepRatio(Context context) { 
    super(context); 

} 

public RelativeLayoutKeepRatio(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    aspectRatio = getAspectRatio(context, attrs); 
} 

public RelativeLayoutKeepRatio(Context context, AttributeSet attrs, 
     int defStyle) { 
    super(context, attrs, defStyle); 
    aspectRatio = getAspectRatio(context, attrs); 
} 

private float getAspectRatio(Context context, AttributeSet attrs) 
{ 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LayoutKeepRatio); 
    float aspectRatio = a.getFloat(R.styleable.LayoutKeepRatio_aspectRatio, 0); 
    if (aspectRatio == 0) 
    { 
     Drawable bg = getBackground(); 
     if (bg != null) 
     { 
      int mBgWidth = bg.getIntrinsicWidth(); 
      int mBgHeight = bg.getIntrinsicHeight(); 
      aspectRatio = (float)mBgWidth/(float)mBgHeight; 
     } 
    } 
    return aspectRatio; 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    if (mLayoutParams == null) { 
     mLayoutParams = getLayoutParams(); 
    } 

    int width = 0; 
    int height = 0; 

    //the width is known and we want to calculate the height 
    if ((mLayoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT || 
     mLayoutParams.width == 0 
     ) && 
     mLayoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) 
    { 
      width = MeasureSpec.getSize(widthMeasureSpec); 
      height = calculateHeight(width, aspectRatio);   
    //the height is known and we want to calculate the width 
    } else if ((mLayoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT || 
      mLayoutParams.height == 0 
      ) && 
      mLayoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) 
    { 
     height = MeasureSpec.getSize(heightMeasureSpec); 
     width = calculateWidth(width, aspectRatio); 
    } 

    else //the width and height are known, we do not need to calculate anything 
    { 
     width = MeasureSpec.getSize(widthMeasureSpec); 
     height = MeasureSpec.getSize(heightMeasureSpec); 
    } 

    int mode = MeasureSpec.EXACTLY; 
    super.onMeasure(MeasureSpec.makeMeasureSpec(width, mode), 
      MeasureSpec.makeMeasureSpec(height, mode)); 
} 

private int calculateWidth(int height, float aspectRatio) 
{ 
    return (int)((float) height * aspectRatio); 
} 

private int calculateHeight(int width, float aspectRatio) 
{ 
    return (int)((float) width/aspectRatio); 
} 
} 


public class WidthResizeTextView extends TextView { 
private float heightPercentage = 0; 

public WidthResizeTextView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ResizeTextView); 
    heightPercentage = a.getFloat(R.styleable.ResizeTextView_HeightPercentage, 0); 
} 

public WidthResizeTextView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ResizeTextView); 
    heightPercentage = a.getFloat(R.styleable.ResizeTextView_HeightPercentage, 0); 
} 

public WidthResizeTextView(Context context) { 
    super(context); 
    // TODO Auto-generated constructor stub 
} 

public float getHeightPercentage(){ 
    return heightPercentage; 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    String text = getText().toString(); 

    int height = MeasureSpec.getSize(heightMeasureSpec); 
    int mode = MeasureSpec.getMode(heightMeasureSpec); 
    if (mode == MeasureSpec.EXACTLY){ 
     setTextSize(TypedValue.COMPLEX_UNIT_PX, (int)((float)height * heightPercentage)); 
     int neededWidth = (int)getPaint().measureText(text); 
     super.onMeasure(MeasureSpec.makeMeasureSpec(neededWidth, mode), 
       MeasureSpec.makeMeasureSpec(height, mode)); 
    } 
    else 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 
} 


public class MyCWGCursorAdapter extends CursorAdapter { 
String path = null; 
Typeface face = null; 
public MyCWGCursorAdapter(Context context, Cursor c, int flags) { 
    super(context, c, flags); 
    path = CommonUtils.getAppPath(context); 
    face = Typeface.createFromAsset(context.getAssets(), "fonts/CANDARA.TTF"); 
} 

@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    RelativeLayout row = (RelativeLayout)inflater.inflate(R.layout.row, parent, false); 
    ViewWrapper wrapper = new ViewWrapper(row); 
    row.setTag(wrapper); 
    return (row); 
} 

@Override 
public void bindView(View row, Context context, Cursor cursor) { 
    // TODO Auto-generated method stub 
    ViewWrapper wrapper = (ViewWrapper)row.getTag(); 
    String nick = cursor.getString(1); 
    String fileName = cursor.getString(2); 
    int count = cursor.getInt(3); 

    Bitmap bitmap = CommonUtils.applyCircleMask(BitmapFactory.decodeFile(path + fileName)); 
    if (bitmap == null) 
     bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.empty_cwg); 
    ImageView picture = wrapper.getImageView(); 
    picture.setImageBitmap(bitmap); 

    WidthResizeTextView nickLabel = wrapper.getNickLabel(); 
    nickLabel.setTypeface(face); 

    WidthResizeTextView nickTextView = wrapper.getNickTextView(); 
    nickTextView.setText(nick); 
    nickTextView.setTypeface(face); 

    WidthResizeTextView countLabel = wrapper.getCountLabel(); 
    countLabel.setTypeface(face); 

    WidthResizeTextView countTextView = wrapper.getCountTextView(); 
    countTextView.setText("" + count); 
    countTextView.setTypeface(face); 

} 

class ViewWrapper { 
    View base; 
    ImageView imageView = null; 
    WidthResizeTextView nickLabel = null; 
    WidthResizeTextView nickTextView = null; 
    WidthResizeTextView countLabel = null; 
    WidthResizeTextView countTextView = null; 

    ViewWrapper(View base){ 
     this.base = base; 
    } 
    ImageView getImageView(){ 
     if (imageView == null){ 
      imageView = (ImageView)base.findViewById(R.id.CWGView); 
     } 
     return imageView; 
    } 

    WidthResizeTextView getNickLabel(){ 
     if (nickLabel == null) { 
      nickLabel = (WidthResizeTextView)base.findViewById(R.id.nickLabel); 
     } 
     return nickLabel; 
    } 

    WidthResizeTextView getNickTextView() { 
     if (nickTextView == null) { 
      nickTextView = (WidthResizeTextView)base.findViewById(R.id.nickTextView); 
     } 
     return nickTextView; 
    } 

    WidthResizeTextView getCountLabel(){ 
     if (countLabel == null) { 
      countLabel = (WidthResizeTextView)base.findViewById(R.id.countLabel); 
     } 
     return countLabel; 
    } 

    WidthResizeTextView getCountTextView() { 
     if (countTextView == null) { 
      countTextView = (WidthResizeTextView)base.findViewById(R.id.countTextView); 
     } 
     return countTextView; 
    } 
} 

} 


<?xml version="1.0" encoding="utf-8"?> 
<com.asharp.android.CWGs.RelativeLayoutKeepRatio 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:custom="http://schemas.android.com/apk/res/com.asharp.android.CWGs" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:background="@drawable/cwg_mycwg_bg" > 

     <ImageView 
      android:id="@+id/CWGView" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_margin="5dip" 
      android:adjustViewBounds="true" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentTop="true"  
      android:src="@drawable/empty_cwg" /> 

     <com.asharp.android.CWGs.WidthResizeTextView 
      android:id="@+id/nickLabel" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_above="@+id/spacer" 
      android:layout_alignParentTop="true" 
      android:layout_marginLeft="10dip" 
      android:layout_toRightOf="@+id/CWGView" 
      android:bufferType="spannable" 
      android:gravity="left|center_vertical" 
      android:singleLine="true" 
      android:text="@string/nick" 
      android:ellipsize="none" 
      android:textColor="@color/MyCWG_field_names" 
      custom:HeightPercentage="0.5" /> 

     <com.asharp.android.CWGs.WidthResizeTextView 
      android:id="@+id/nickTextView" 
      android:layout_toRightOf="@+id/countLabel" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_alignParentTop="true" 
      android:layout_above="@+id/spacer" 
      android:layout_marginLeft = "10dip" 
      android:gravity="left|center_vertical" 
      android:text="0" 
      android:singleLine="true" 
      android:ellipsize="none" 
      android:bufferType="spannable" 
      custom:HeightPercentage="0.5" 
      android:background="#00FF00" 
      android:textColor="@color/MyCWG_field_values"/> 
     <View 
      android:id="@+id/spacer" 
      android:layout_width="match_parent" 
      android:layout_toRightOf="@id/CWGView" 
      android:layout_height="1px" 
      android:layout_centerVertical="true" 
      android:visibility="invisible"/>    
     <com.asharp.android.CWGs.WidthResizeTextView 
      android:id="@+id/countLabel" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_below="@id/spacer" 
      android:layout_marginLeft="10dip" 
      android:gravity="left|center_vertical" 
      android:layout_toRightOf="@+id/CWGView" 
      android:layout_alignParentBottom="true" 
      android:text="@string/count_colon" 
      android:ellipsize="none" 
      android:singleLine="true" 
      android:textColor="@color/MyCWG_field_names" 
      android:bufferType="spannable" 
      custom:HeightPercentage="0.5" /> 
     <com.asharp.android.CWGs.WidthResizeTextView 
      android:id="@+id/countTextView" 
      android:layout_toRightOf="@id/countLabel" 
      android:layout_alignParentBottom="true" 
      android:layout_below="@id/spacer" 
      android:layout_marginLeft = "10dip" 
      android:gravity="left|center_vertical" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:singleLine="true" 
      android:ellipsize="none" 
      android:bufferType="spannable" 
      custom:HeightPercentage="0.5" 
      android:text="0" 
      android:textColor="@color/MyCWG_field_values"/> 


</com.asharp.android.CWGs.RelativeLayoutKeepRatio> 


你們當中有誰見過這樣的行爲?我花了幾天的時間試圖解決這個問題,但我沒有成功:-(我相信這跟WidthResizeTextView有關,因爲我花了很長時間才把它變成這樣工作,謝謝你幫幫我!

+0

@ user2582585:從您的編輯中,似乎這是您自己的文章,但在以user2579825身份登錄之前。你應該只使用一個帳戶。要設置它,請按照此幫助頁上的說明進行操作:http://stackoverflow.com/help/merging-accounts – oberlies

回答

0

您可能需要重新設計使用標準的瀏覽你的XML像

  • 一個ConstraintLayout而不是RelativeLayout集裝箱
  • Guidelines或百分比高度/寬度來定位你的部件

有一個看看ConstraintLayout documentation

相關問題