2013-07-13 4 views
1

Я нашел, что подобная тема была решена здесь несколько раз, но мне не удалось найти решение для моей проблемы.

Я использую ListView с пользовательским CursorAdapter, который берет данные из базы данных. Строки создаются XML-файлом на основе настраиваемого Relative Layout, который имеет изображение в качестве фона и должен поддерживать пропорции изображения. Ширина Relative Layout устанавливается в match_parent, а затем вычисляется высота по формату изображения.

В Относительной компоновке есть 5 элементов (на самом деле их 6, 6-й - пустой. Простое разделение строки на две половины): 1 ImageView и 4 пользовательских текстовых вида, которые изменяются до автоматического размера текст в зависимости от высоты TextView (размер текста задается в процентах, здесь параметр heightPercentage равен 0,5, поэтому размер текста должен составлять 50% от высоты TextView).

Все работает, но иногда некоторые из них не отображаются правильно (размер текста кажется правильным, но ширина TextView слишком короткая. После прокрутки нескольких элементов вниз и обратно все в порядке .

Вот фотографии:

Correct один (после прокрутки):
Correct

Некорректное один (до свитка)
Incorrect

Edit: Я попытался использовать некоторые из текстов autosize textviews, найденных в Интернете, и поведение более или менее похоже; иногда представление не отображается должным образом до тех пор, пока прокрутка ocurrs не будет отображаться правильно, но после прокрутки она перепутана ... мне кажется, что существуют определенные правила для пользовательских представлений, используемых в строках Listview, которые я делаю не понимаю :-(Я пытался использовать методы, такие как invalidateViews(), notifyDataSetChanged() в разных местах кода, иногда даже как runInIOThread(), но без успеха поведение никогда не изменяется ...
Android ListView с пользовательским autosize Textview - некоторые элементы не отображаются должным образом до прокрутки



Ниже приведен код относительного макета пользовательского называется RelativeLayoutKeepRatio, пользовательское TextView под названием WidthResizeTextView и пользовательское 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: Из вашего редактирования кажется, что это ваш собственный пост, но прежде чем вы вошли в систему как пользователь2579825. Вы должны использовать только одну учетную запись. Чтобы установить это прямо, следуйте инструкциям на этой странице справки: http://stackoverflow.com/help/merging-accounts – oberlies

ответ

0

Вы можете перепроектировать XML, используя стандартные представления, как

  • ConstraintLayout вместо RelativeLayout в качестве контейнера
  • Guidelines или процентов высоты/ширины расположить виджеты

Имеют посмотрите на ConstraintLayout documentation.