2016-09-26 73 views
2

所有按钮文本都是从服务器动态生成的。我已经尝试了所有基本给定的布局来形成这种设计,但无法获得期望的结果。请帮助我,我怎样才能解决这个设计在android中的实现。无法找到以下设计的布局

Design which needs to be implemented.

+0

没有Android视图可以做到这一点。有没有其他模式,然后每行1-3个随机按钮 –

+0

试试这个:https://github.com/ApmeM/android-flowlayout 或这个:https://android-arsenal.com/details/1/2566 –

+0

你只需要一行2和另一行3或根据可用空间可能会更像标签? –

回答

0

将此添加到您的布局中。

<LinearLayout 
       android:id="@+id/tagviews" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentLeft="true" 
       android:orientation="vertical" > 

在Java类

tagViews= (LinearLayout)findViewById(R.id.tagviews); 
tagViews.removeAllViews(); 
     LinearLayout ll = new LinearLayout(context); 
     ll.setOrientation(LinearLayout.HORIZONTAL); 
     ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); 
     LinearLayout childView; 
     int remainingWidth, count = tagViews.getChildCount(); 
     if (count <= 0) 
      tagViews.addView(ll); 
     TextView tagText; 

     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
       LinearLayout.LayoutParams.WRAP_CONTENT); 
     params.setMargins(5, 5, 5, 5); 

     int width = 0; 
     WindowManager w = ((Activity) context).getWindowManager(); 
     Point size = new Point(); 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 
      w.getDefaultDisplay().getSize(size); 
      width = size.x; 
     } else { 
//   Display d = w.getDefaultDisplay(); 
//   width = d.getWidth(); 
      DisplayMetrics displaymetrics = new DisplayMetrics(); 
      getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
      width = displaymetrics.widthPixels; 
      //int screenHeight = displaymetrics.heightPixels; 
     } 
     try { 
      // you might have some array from where you want to set Tags 
      for (int k = 0; k < arr.length(); k++) { 
       JSONObject obj = arr.getJSONObject(k);     
       final String name = obj.getString("name"); 
       for (int i = 0; i < tagViews.getChildCount(); i++) { 
        childView = (LinearLayout) tagViews.getChildAt(i); 
        tagText = new TextView(context);      
        tagText.setText(name); 
        tagText.setLayoutParams(params); 
        tagText.setPadding(10, 5, 10, 5); 
        tagText.setBackgroundColor(Color.rgb(0xee, 0xee, 0xee)); 
        tagText.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View v) { 
          // for handling clicks on tags 
         } 
        }); 
        // count = tagViews.getChildCount(); 
        childView.measure(0, 0); 
        remainingWidth = width - childView.getMeasuredWidth(); 
        //// Log.v("subcriptionAdapter", "remaining width=" + remainingWidth + " childview width= " + childView.getMeasuredWidth()); 
        try { 
         if (remainingWidth > childView.getMeasuredWidth()) { 
          childView.addView(tagText); 
          childView.invalidate(); 
          break; 
         } else if ((i == tagViews.getChildCount() - 1) && (remainingWidth < childView.getMeasuredWidth())) { 
          childView = new LinearLayout(context); 
          childView.setOrientation(LinearLayout.HORIZONTAL); 
          childView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); 
          childView.addView(tagText); 
          tagViews.addView(childView); 
          childView.invalidate(); 
          break; 
         } else { 
          continue; 
         } 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } catch (Exception e) { 
      // TODO: handle exception 
     } 
     tagViews.invalidate(); 

它为我试试吧,让我知道....

+0

我可以知道什么是持有人吗?它与RecyvlerView Holder有关吗? –

+0

@AnkitGupta我已经编辑过,实际上我在我的recyclerview持有者适配器类中使用了这个,所以在上面的代码中粘贴代码时,错误的持有者在几个点上没有被删除。我现在编辑它。你可以使用它。 –

+0

感谢您的帮助。我标记这个权利,因为它是根据需要,我面临的唯一的错误是,几个按钮有底部溶解。可能是由于保证金,但也尝试过。将再次粘贴图片。 –

1

您所需要的部件是自动调整的TextView

尝试下面的类,它可以帮助你

import android.annotation.TargetApi; 
import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.RectF; 
import android.os.Build; 
import android.text.Layout.Alignment; 
import android.text.StaticLayout; 
import android.text.TextPaint; 
import android.util.AttributeSet; 
import android.util.SparseIntArray; 
import android.util.TypedValue; 
import android.widget.TextView; 

public class AutoResizeTextView extends TextView { 
private interface SizeTester { 
    /** 
    * 
    * @param suggestedSize 
    *   Size of text to be tested 
    * @param availableSpace 
    *   available space in which text must fit 
    * @return an integer < 0 if after applying {@code suggestedSize} to 
    *   text, it takes less space than {@code availableSpace}, > 0 
    *   otherwise 
    */ 
    public int onTestSize(int suggestedSize, RectF availableSpace); 
} 

private RectF mTextRect = new RectF(); 

private RectF mAvailableSpaceRect; 

private SparseIntArray mTextCachedSizes; 

private TextPaint mPaint; 

private float mMaxTextSize; 

private float mSpacingMult = 1.0f; 

private float mSpacingAdd = 0.0f; 

private float mMinTextSize = 20; 

private int mWidthLimit; 

private static final int NO_LINE_LIMIT = -1; 
private int mMaxLines; 

private boolean mEnableSizeCache = true; 
private boolean mInitializedDimens; 

public AutoResizeTextView(Context context) { 
    super(context); 
    initialize(); 
} 

public AutoResizeTextView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initialize(); 
} 

public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    initialize(); 
} 

private void initialize() { 
    mPaint = new TextPaint(getPaint()); 
    mMaxTextSize = getTextSize(); 
    mAvailableSpaceRect = new RectF(); 
    mTextCachedSizes = new SparseIntArray(); 
    if (mMaxLines == 0) { 
     // no value was assigned during construction 
     mMaxLines = NO_LINE_LIMIT; 
    } 
} 

@Override 
public void setTextSize(float size) { 
    mMaxTextSize = size; 
    mTextCachedSizes.clear(); 
    adjustTextSize(); 
} 

@Override 
public void setMaxLines(int maxlines) { 
    super.setMaxLines(maxlines); 
    mMaxLines = maxlines; 
    adjustTextSize(); 
} 

public int getMaxLines() { 
    return mMaxLines; 
} 

@Override 
public void setSingleLine() { 
    super.setSingleLine(); 
    mMaxLines = 1; 
    adjustTextSize(); 
} 

@Override 
public void setSingleLine(boolean singleLine) { 
    super.setSingleLine(singleLine); 
    if (singleLine) { 
     mMaxLines = 1; 
    } else { 
     mMaxLines = NO_LINE_LIMIT; 
    } 
    adjustTextSize(); 
} 

@Override 
public void setLines(int lines) { 
    super.setLines(lines); 
    mMaxLines = lines; 
    adjustTextSize(); 
} 

@Override 
public void setTextSize(int unit, float size) { 
    Context c = getContext(); 
    Resources r; 

    if (c == null) 
     r = Resources.getSystem(); 
    else 
     r = c.getResources(); 
    mMaxTextSize = TypedValue.applyDimension(unit, size, 
      r.getDisplayMetrics()); 
    mTextCachedSizes.clear(); 
    adjustTextSize(); 
} 

@Override 
public void setLineSpacing(float add, float mult) { 
    super.setLineSpacing(add, mult); 
    mSpacingMult = mult; 
    mSpacingAdd = add; 
} 

/** 
* Set the lower text size limit and invalidate the view 
* 
* @param minTextSize 
*/ 
public void setMinTextSize(float minTextSize) { 
    mMinTextSize = minTextSize; 
    adjustTextSize(); 
} 

private void adjustTextSize() { 
    if (!mInitializedDimens) { 
     return; 
    } 
    int startSize = (int) mMinTextSize; 
    int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom() 
      - getCompoundPaddingTop(); 
    mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft() 
      - getCompoundPaddingRight(); 
    mAvailableSpaceRect.right = mWidthLimit; 
    mAvailableSpaceRect.bottom = heightLimit; 
    super.setTextSize(
      TypedValue.COMPLEX_UNIT_PX, 
      efficientTextSizeSearch(startSize, (int) mMaxTextSize, 
        mSizeTester, mAvailableSpaceRect)); 
} 

private final SizeTester mSizeTester = new SizeTester() { 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    @Override 
    public int onTestSize(int suggestedSize, RectF availableSPace) { 
     mPaint.setTextSize(suggestedSize); 
     String text = getText().toString(); 
     boolean singleline = getMaxLines() == 1; 
     if (singleline) { 
      mTextRect.bottom = mPaint.getFontSpacing(); 
      mTextRect.right = mPaint.measureText(text); 
     } else { 
      StaticLayout layout = new StaticLayout(text, mPaint, 
        mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult, 
        mSpacingAdd, true); 
      // return early if we have more lines 
      if (getMaxLines() != NO_LINE_LIMIT 
        && layout.getLineCount() > getMaxLines()) { 
       return 1; 
      } 
      mTextRect.bottom = layout.getHeight(); 
      int maxWidth = -1; 
      for (int i = 0; i < layout.getLineCount(); i++) { 
       if (maxWidth < layout.getLineWidth(i)) { 
        maxWidth = (int) layout.getLineWidth(i); 
       } 
      } 
      mTextRect.right = maxWidth; 
     } 

     mTextRect.offsetTo(0, 0); 
     if (availableSPace.contains(mTextRect)) { 
      // may be too small, don't worry we will find the best match 
      return -1; 
     } else { 
      // too big 
      return 1; 
     } 
    } 
}; 

/** 
* Enables or disables size caching, enabling it will improve performance 
* where you are animating a value inside TextView. This stores the font 
* size against getText().length() Be careful though while enabling it as 0 
* takes more space than 1 on some fonts and so on. 
* 
* @param enable 
*   enable font size caching 
*/ 
public void enableSizeCache(boolean enable) { 
    mEnableSizeCache = enable; 
    mTextCachedSizes.clear(); 
    adjustTextSize(getText().toString()); 
} 

private int efficientTextSizeSearch(int start, int end, 
     SizeTester sizeTester, RectF availableSpace) { 
    if (!mEnableSizeCache) { 
     return binarySearch(start, end, sizeTester, availableSpace); 
    } 
    int key = getText().toString().length(); 
    int size = mTextCachedSizes.get(key); 
    if (size != 0) { 
     return size; 
    } 
    size = binarySearch(start, end, sizeTester, availableSpace); 
    mTextCachedSizes.put(key, size); 
    return size; 
} 

private static int binarySearch(int start, int end, SizeTester sizeTester, 
     RectF availableSpace) { 
    int lastBest = start; 
    int lo = start; 
    int hi = end - 1; 
    int mid = 0; 
    while (lo <= hi) { 
     mid = (lo + hi) >>> 1; 
     int midValCmp = sizeTester.onTestSize(mid, availableSpace); 
     if (midValCmp < 0) { 
      lastBest = lo; 
      lo = mid + 1; 
     } else if (midValCmp > 0) { 
      hi = mid - 1; 
      lastBest = hi; 
     } else { 
      return mid; 
     } 
    } 
    // make sure to return last best 
    // this is what should always be returned 
    return lastBest; 

} 

@Override 
protected void onTextChanged(final CharSequence text, final int start, 
     final int before, final int after) { 
    super.onTextChanged(text, start, before, after); 
    adjustTextSize(); 
} 

@Override 
protected void onSizeChanged(int width, int height, int oldwidth, 
     int oldheight) { 
    mInitializedDimens = true; 
    mTextCachedSizes.clear(); 
    super.onSizeChanged(width, height, oldwidth, oldheight); 
    if (width != oldwidth || height != oldheight) { 
     adjustTextSize(); 
    } 
} 
} 

有一个图书馆也可在github上

https://github.com/grantland/android-autofittextview

快乐编码!

+0

如果有帮助,您可以标记为正确的答案以帮助其他人:) –

0

Android已经提供了一个名为Chips视图组件,使您可以包括文本,图像,图标等。您可以尝试将芯片与staggeredGrid结合在一起以实现上述视图。或者,您可以尝试使用ChipView,因为它是高度可定制的。要使用您自己的布局,您需要创建一个适配器并实施ChipViewAdapter。详细了解ChipView。 - https://github.com/Plumillon/ChipView

public class MainChipViewAdapter extends ChipViewAdapter { 
public MainChipViewAdapter(Context context) { 
    super(context); 
} 

@Override 
public int getLayoutRes(int position) { 
    Tag tag = (Tag) getChip(position); 

    switch (tag.getType()) { 
     default: 
     case 2: 
     case 4: 
      return 0; 

     case 1: 
     case 5: 
      return R.layout.chip_double_close; 

     case 3: 
      return R.layout.chip_close; 
    } 
}