Java 为什么当我滚动查看时,我的文本视图文本大小会改变?(使用AutoResizeTextView)
我使用一个类来调整列表(RecycleView)文本中文本视图的大小以适应宽度。最初,所有列表中的文本视图都会进行完美调整。然而,当我向上滚动时,文本大小似乎与其他行混淆了。我知道这与它如何在RecycleView中重用有关,但有没有办法解决这个问题?我不想在初次加载后更改TextView字体大小。它是静态数据 这是我的适配器Java 为什么当我滚动查看时,我的文本视图文本大小会改变?(使用AutoResizeTextView),java,android,android-recyclerview,Java,Android,Android Recyclerview,我使用一个类来调整列表(RecycleView)文本中文本视图的大小以适应宽度。最初,所有列表中的文本视图都会进行完美调整。然而,当我向上滚动时,文本大小似乎与其他行混淆了。我知道这与它如何在RecycleView中重用有关,但有没有办法解决这个问题?我不想在初次加载后更改TextView字体大小。它是静态数据 这是我的适配器 public class EventsAdapter extends RecyclerView.Adapter<EventsAdapter.EventHolder&
public class EventsAdapter extends RecyclerView.Adapter<EventsAdapter.EventHolder> {
private Event[] eventslistData;
private LayoutInflater layoutInflater;
public EventsAdapter(Event[] eventsListData, Context c) {
this.layoutInflater = LayoutInflater.from(c);
this.eventslistData = eventsListData;
}
@Override
public EventHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.event_list_item, parent, false);
return new EventHolder(view);
}
@Override
public void onBindViewHolder(EventHolder holder, int position) {
Event event = eventslistData[position];
holder.eventNameTextView.setText(event.getEventName());
holder.eventLocationTextView.setText(event.getEventLocation());
holder.eventDateTextView.setText(event.getEventDate());
}
@Override
public int getItemCount() {
return eventslistData.length;
}
class EventHolder extends RecyclerView.ViewHolder {
private TextView eventNameTextView;
private TextView eventLocationTextView;
private TextView eventDateTextView;
public EventHolder(View itemView) {
super(itemView);
eventNameTextView = (TextView)itemView.findViewById(R.id.eventNameTextView);
eventLocationTextView = (TextView)itemView.findViewById(R.id.eventLocationTextView);
eventDateTextView = (TextView)itemView.findViewById(R.id.eventDateTextView);
}
}
}
公共类EventsAdapter扩展了RecyclerView.Adapter{
私有事件[]事件列表数据;
私人停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场;
公共事件适配器(事件[]事件列表数据,上下文c){
this.layoutInflater=layoutInflater.from(c);
this.eventslistData=eventslistData;
}
@凌驾
public EventHolder onCreateViewHolder(视图组父级,int-viewType){
视图=布局更平坦。充气(R.layout.event\u list\u项,父项,false);
返回新的事件持有者(视图);
}
@凌驾
public void onBindViewHolder(事件持有者,int位置){
事件=事件列表数据[位置];
holder.eventNameTextView.setText(event.getEventName());
holder.eventLocationTextView.setText(event.getEventLocation());
holder.eventDateTextView.setText(event.getEventDate());
}
@凌驾
public int getItemCount(){
返回eventslistData.length;
}
类EventHolder扩展了RecyclerView.ViewHolder{
私有文本视图事件名称文本视图;
私有文本视图事件位置文本视图;
私有文本视图eventDateTextView;
公共事件持有者(查看项目视图){
超级(项目视图);
eventNameTextView=(TextView)itemView.findViewById(R.id.eventNameTextView);
eventLocationTextView=(TextView)itemView.findViewById(R.id.eventLocationTextView);
eventDateTextView=(TextView)itemView.findViewById(R.id.eventDateTextView);
}
}
}
以防万一这里是我所有的AutoResizeTextView类
public class AutoResizeTextView extends TextView {
// Minimum text size for this text view
public static final float MIN_TEXT_SIZE = 12;
// Interface for resize notifications
public interface OnTextResizeListener {
public void onTextResize(TextView textView, float oldSize, float newSize);
}
// Our ellipse string
private static final String mEllipsis = "...";
// Registered resize listener
private OnTextResizeListener mTextResizeListener;
// Flag for text and/or size changes to force a resize
private boolean mNeedsResize = false;
// Text size that is set from code. This acts as a starting point for resizing
private float mTextSize;
// Temporary upper bounds on the starting text size
private float mMaxTextSize = 0;
// Lower bounds for text size
private float mMinTextSize = MIN_TEXT_SIZE;
// Text view line spacing multiplier
private float mSpacingMult = 1.0f;
// Text view additional line spacing
private float mSpacingAdd = 0.0f;
// Add ellipsis to text that overflows at the smallest text size
private boolean mAddEllipsis = true;
// Default constructor override
public AutoResizeTextView(Context context) {
this(context, null);
}
// Default constructor when inflating from XML file
public AutoResizeTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
// Default constructor override
public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mTextSize = getTextSize();
}
/**
* When text changes, set the force resize flag to true and reset the text size.
*/
@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
mNeedsResize = true;
// Since this view may be reused, it is good to reset the text size
resetTextSize();
}
/**
* If the text view size changed, set the force resize flag to true
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw || h != oldh) {
mNeedsResize = true;
}
}
/**
* Register listener to receive resize notifications
* @param listener
*/
public void setOnResizeListener(OnTextResizeListener listener) {
mTextResizeListener = listener;
}
/**
* Override the set text size to update our internal reference values
*/
@Override
public void setTextSize(float size) {
super.setTextSize(size);
mTextSize = getTextSize();
}
/**
* Override the set text size to update our internal reference values
*/
@Override
public void setTextSize(int unit, float size) {
super.setTextSize(unit, size);
mTextSize = getTextSize();
}
/**
* Override the set line spacing to update our internal reference values
*/
@Override
public void setLineSpacing(float add, float mult) {
super.setLineSpacing(add, mult);
mSpacingMult = mult;
mSpacingAdd = add;
}
/**
* Set the upper text size limit and invalidate the view
* @param maxTextSize
*/
public void setMaxTextSize(float maxTextSize) {
mMaxTextSize = maxTextSize;
requestLayout();
invalidate();
}
/**
* Return upper text size limit
* @return
*/
public float getMaxTextSize() {
return mMaxTextSize;
}
/**
* Set the lower text size limit and invalidate the view
* @param minTextSize
*/
public void setMinTextSize(float minTextSize) {
mMinTextSize = minTextSize;
requestLayout();
invalidate();
}
/**
* Return lower text size limit
* @return
*/
public float getMinTextSize() {
return mMinTextSize;
}
/**
* Set flag to add ellipsis to text that overflows at the smallest text size
* @param addEllipsis
*/
public void setAddEllipsis(boolean addEllipsis) {
mAddEllipsis = addEllipsis;
}
/**
* Return flag to add ellipsis to text that overflows at the smallest text size
* @return
*/
public boolean getAddEllipsis() {
return mAddEllipsis;
}
/**
* Reset the text to the original size
*/
public void resetTextSize() {
if (mTextSize > 0) {
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
mMaxTextSize = mTextSize;
}
}
/**
* Resize text after measuring
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (changed || mNeedsResize) {
int widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight();
int heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop();
resizeText(widthLimit, heightLimit);
}
super.onLayout(changed, left, top, right, bottom);
}
/**
* Resize the text size with default width and height
*/
public void resizeText() {
int heightLimit = getHeight() - getPaddingBottom() - getPaddingTop();
int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight();
resizeText(widthLimit, heightLimit);
}
/**
* Resize the text size with specified width and height
* @param width
* @param height
*/
public void resizeText(int width, int height) {
CharSequence text = getText();
// Do not resize if the view does not have dimensions or there is no text
if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
return;
}
if (getTransformationMethod() != null) {
text = getTransformationMethod().getTransformation(text, this);
}
// Get the text view's paint object
TextPaint textPaint = getPaint();
// Store the current text size
float oldTextSize = textPaint.getTextSize();
// If there is a max text size set, use the lesser of that and the default text size
float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;
// Get the required text height
int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
// Until we either fit within our text view or we had reached our min text size, incrementally try smaller sizes
while (textHeight > height && targetTextSize > mMinTextSize) {
targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
textHeight = getTextHeight(text, textPaint, width, targetTextSize);
}
// If we had reached our minimum text size and still don't fit, append an ellipsis
if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
// Draw using a static layout
// modified: use a copy of TextPaint for measuring
TextPaint paint = new TextPaint(textPaint);
// Draw using a static layout
StaticLayout layout = new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
// Check that we have a least one line of rendered text
if (layout.getLineCount() > 0) {
// Since the line at the specific vertical position would be cut off,
// we must trim up to the previous line
int lastLine = layout.getLineForVertical(height) - 1;
// If the text would not even fit on a single line, clear it
if (lastLine < 0) {
setText("");
}
// Otherwise, trim to the previous line and add an ellipsis
else {
int start = layout.getLineStart(lastLine);
int end = layout.getLineEnd(lastLine);
float lineWidth = layout.getLineWidth(lastLine);
float ellipseWidth = textPaint.measureText(mEllipsis);
// Trim characters off until we have enough room to draw the ellipsis
while (width < lineWidth + ellipseWidth) {
lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
}
setText(text.subSequence(0, end) + mEllipsis);
}
}
}
// Some devices try to auto adjust line spacing, so force default line spacing
// and invalidate the layout as a side effect
setTextSize(TypedValue.COMPLEX_UNIT_PX, targetTextSize);
setLineSpacing(mSpacingAdd, mSpacingMult);
// Notify the listener if registered
if (mTextResizeListener != null) {
mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
}
// Reset force resize flag
mNeedsResize = false;
}
// Set the text size of the text paint object and use a static layout to render text off screen before measuring
private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) {
// modified: make a copy of the original TextPaint object for measuring
// (apparently the object gets modified while measuring, see also the
// docs for TextView.getPaint() (which states to access it read-only)
TextPaint paintCopy = new TextPaint(paint);
// Update the text paint object
paintCopy.setTextSize(textSize);
// Measure using a static layout
StaticLayout layout = new StaticLayout(source, paintCopy, width, Layout.Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
return layout.getHeight();
}
}
公共类AutoResizeTextView扩展了TextView{
//此文本视图的最小文本大小
公共静态最终浮点最小值\文本\大小=12;
//调整大小通知的接口
公共接口OnTextResizeListener{
public void onTextResize(TextView TextView、float oldSize、float newSize);
}
//我们的椭圆弦
私有静态最终字符串mEllipsis=“…”;
//注册调整侦听器大小
私有OnTextResizeListener mTextResizeListener;
//文本和/或大小更改的标志,以强制调整大小
私有布尔值mNeedsResize=false;
//根据代码设置的文本大小。这是调整大小的起点
私有浮动mTextSize;
//起始文本大小的临时上限
私有浮点mMaxTextSize=0;
//文本大小的下限
私有浮点mMinTextSize=MIN\u TEXT\u SIZE;
//文本视图行距倍增器
私人浮动mSpacingMult=1.0f;
//文本视图附加行间距
私人浮动mSpacingAdd=0.0f;
//将省略号添加到以最小文本大小溢出的文本中
私有布尔mAddEllipsis=true;
//默认构造函数重写
公共AutoResizeTextView(上下文){
这个(上下文,空);
}
//从XML文件膨胀时的默认构造函数
公共AutoResizeTextView(上下文、属性集属性){
这(上下文,属性,0);
}
//默认构造函数重写
公共AutoResizeTextView(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
mTextSize=getTextSize();
}
/**
*文本更改时,请将“强制调整大小”标志设置为true并重置文本大小。
*/
@凌驾
受保护的void onTextChanged(最终字符序列文本、最终整数开始、最终整数之前、最终整数之后){
mNeedsResize=true;
//由于此视图可以重用,因此最好重置文本大小
resetTextSize();
}
/**
*如果文字视图大小已更改,请将“强制调整大小”标志设置为true
*/
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
如果(w!=oldw | | h!=oldh){
mNeedsResize=true;
}
}
/**
*注册侦听器以接收调整大小通知
*@param侦听器
*/
public void setOnResizeListener(OnTextResizeListener侦听器){
mTextResizeListener=监听器;
}
/**
*覆盖设置的文本大小以更新内部参考值
*/
@凌驾
公共void setTextSize(浮动大小){
super.setTextSize(大小);
mTextSize=getTextSize();
}
/**
*覆盖设置的文本大小以更新内部参考值
*/
@凌驾
公共void setTextSize(整数单位,浮点大小){
super.setTextSize(单位,大小);
mTextSize=getTextSize();
}
/**
*覆盖设置的行距以更新内部参考值
*/
@凌驾
公共void设置行间距(浮动添加、浮动多个){
super.setlinespace(添加,多个);
mSpacingMult=mult;
mSpacingAdd=添加;
}
/**
*设置文本大小上限并使视图无效
*@param maxTextSize
*/
公共void setMaxTextSize(浮动maxTextSize){
mmaxtsize=maxTextSize;
requestLayout();
使无效();
}
/**
*返回文本大小上限
*@返回
*/
公共浮点getMaxTextSize(){
返回mMaxTextSize;
}
/**
*设置较低的文本大小限制并使视图无效
*@param minTextSize
*/
公共void setMinTextSize(浮点minTextSize){
mMinTextSize=minTextSize;
requestLayout();
使无效();
}
/**
*返回较低的文本大小限制
*
@Override
public int getItemViewType(int position){
return position;
}