带有徽章

时间:2018-03-20 11:43:15

标签: android xamarin xamarin.android

我在一小时的大部分时间里都遇到过这个特殊布局的问题,而且我似乎无法按预期进行布局。我已经完成了关于标签的这种格式的通常谷歌搜索,似乎没有什么是我正在追求的。

我有一个TabLayout,其中选项卡是垂直布局的,使用ImageView和TextView使用默认的选项卡视图。

看起来像这样:

Home tab

理想情况下,我希望能够模仿此布局并将TextView锚定为图标右上方的徽章计数器。

像这样:

Home tab with badge example

因此,考虑到这一点,我发现了默认选项卡布局实际显示的方式,它使用了默认ID,因此我不必以编程方式分配它们,我认为这很漂亮:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
  <LinearLayout
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="vertical"
      android:layout_marginBottom="4dp"
      android:layout_marginTop="4dp">
    <ImageView
        android:id="@android:id/icon"
        android:layout_gravity="center"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:scaleType="centerInside" />
    <TextView
        android:id="@android:id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@drawable/tab_selector"
        android:ellipsize="end"
        android:textAllCaps="true"
        android:gravity="center"
        android:maxLines="2" />
  </LinearLayout>
  <TextView
      android:id="@+id/badgeCounter"
      android:layout_width="wrap_content"
      android:layout_height="20dp"
      android:minWidth="20dp"
      android:textAlignment="center"
      android:background="@drawable/count_background"
      android:textSize="15sp" />
</RelativeLayout>

经过大量的修补和尝试不同的事情,我得到了这个:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_marginBottom="4dp"
    android:layout_marginTop="4dp"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/iconFrame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="2dp"
        android:layout_centerHorizontal="true"
        android:layout_above="@android:id/text1">
        <ImageView
            android:id="@android:id/icon"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:scaleType="centerInside"
            android:src="@drawable/tab_home" />
    </FrameLayout>
    <TextView
        android:id="@android:id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@drawable/tab_selector"
        android:ellipsize="end"
        android:textAllCaps="true"
        android:gravity="center"
        android:maxLines="2"
        android:text="Home"
        android:layout_marginBottom="7dp"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true" />
    <TextView
        android:id="@+id/badgeCounter"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:minWidth="20dp"
        android:layout_toRightOf="@+id/iconFrame"
        android:textColor="@color/FeatureFontColour"
        android:textAlignment="center"
        android:background="@drawable/count_background"
        android:textSize="15sp"
        android:layout_alignTop="@+id/iconFrame" />
</RelativeLayout>

无论我尝试什么,我都无法获得徽章TextView出现在正确的位置,我已经尝试删除线性布局,以便我可以将其设置为Layout_RightOf @android:id / icon,I'尝试在框架中包装图标并设置Layout_RightOf,而不是仅仅在创建徽章TextView之前定位图标等。

这是我能得到的(Spoiler,不是那么接近):

Tab

任何帮助都会受到赞赏,我不确定我到底错过了什么,但可能性很大。

3 个答案:

答案 0 :(得分:1)

试试这个:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="wrap_content"
  android:layout_marginBottom="4dp"
  android:layout_marginTop="4dp"
  android:clipChildren="false"
  android:layout_height="match_parent">
  <FrameLayout
    android:id="@+id/iconFrame"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:clipToPadding="false"
    android:layout_marginBottom="2dp"
    android:layout_centerHorizontal="true"
    android:clipChildren="false"
    android:layout_above="@android:id/text1">
    <ImageView
        android:id="@android:id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:scaleType="centerInside"
        android:src="@drawable/tab_home" />
    <TextView
        android:id="@+id/badgeCounter"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:minWidth="20dp"
        android:textColor="@color/FeatureFontColour"
        android:textAlignment="center"
        android:background="@drawable/count_background"
        android:layout_gravity="right"
        android:layout_marginRight="-10dp"
        android:layout_marginTop="-10dp"
        android:textSize="15sp"/>
   </FrameLayout>
   <TextView
    android:id="@android:id/text1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@drawable/tab_selector"
    android:ellipsize="end"
    android:textAllCaps="true"
    android:gravity="center"
    android:maxLines="2"
    android:text="Home"
    android:layout_marginBottom="7dp"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true" />
 </RelativeLayout>

您可以使用边距右/顶值进行微调。

答案 1 :(得分:1)

创建可绘制图层以在第一层上显示菜单项并在其上显示徽章

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:drawable="@drawable/ic_cart"
    android:gravity="center" />
      <item
    android:id="@+id/ic_badge"
    android:drawable="@drawable/ic_cart" />
</layer-list>

为我们的活动创建菜单以显示菜单项的计数。

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.example.mobikul.MainActivity" >

<item
    android:id="@+id/action_cart"
    android:icon="@drawable/ic_menu_cart"
    android:title="@string/action_cart"
    app:showAsAction="always" />

创建灵活高效的自定义BagdeDrawable类来绘制看起来像计数的视图

public class BadgeDrawable extends Drawable {

private Paint mBadgePaint;
private Paint mBadgePaint1;
private Paint mTextPaint;
private Rect mTxtRect = new Rect();

private String mCount = "";
private boolean mWillDraw;

public BadgeDrawable(Context context) {
    float mTextSize = context.getResources().getDimension(R.dimen.badge_text_size);

    mBadgePaint = new Paint();
    mBadgePaint.setColor(Color.RED);
    mBadgePaint.setAntiAlias(true);
    mBadgePaint.setStyle(Paint.Style.FILL);
    mBadgePaint1 = new Paint();
    mBadgePaint1.setColor(ContextCompat.getColor(context.getApplicationContext(), R.color.grey_ivory5));
    mBadgePaint1.setAntiAlias(true);
    mBadgePaint1.setStyle(Paint.Style.FILL);

    mTextPaint = new Paint();
    mTextPaint.setColor(Color.WHITE);
    mTextPaint.setTypeface(Typeface.DEFAULT);
    mTextPaint.setTextSize(mTextSize);
    mTextPaint.setAntiAlias(true);
    mTextPaint.setTextAlign(Paint.Align.CENTER);
}

@Override
public void draw(Canvas canvas) {



    if (!mWillDraw) {
        return;
    }
    Rect bounds = getBounds();
    float width = bounds.right - bounds.left;
    float height = bounds.bottom - bounds.top;

    // Position the badge in the top-right quadrant of the icon.

        /*Using Math.max rather than Math.min */

    float radius = ((Math.max(width, height) / 2)) / 2;
    float centerX = (width - radius - 1) +5;
    float centerY = radius -5;
    if(mCount.length() <= 2){
        // Draw badge circle.
        canvas.drawCircle(centerX, centerY, (int)(radius+7.5), mBadgePaint1);
        canvas.drawCircle(centerX, centerY, (int)(radius+5.5), mBadgePaint);
    }
    else{
        canvas.drawCircle(centerX, centerY, (int)(radius+8.5), mBadgePaint1);
        canvas.drawCircle(centerX, centerY, (int)(radius+6.5), mBadgePaint);
    }
    mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect);
    float textHeight = mTxtRect.bottom - mTxtRect.top;
    float textY = centerY + (textHeight / 2f);
    if(mCount.length() > 2)
        canvas.drawText("99+", centerX, textY, mTextPaint);
    else
        canvas.drawText(mCount, centerX, textY, mTextPaint);
}

/*
Sets the count (i.e notifications) to display.
 */
public void setCount(String count) {
    mCount = count;

    // Only draw a badge if there are notifications.
    mWillDraw = !count.equalsIgnoreCase("0");
    invalidateSelf();
}

@Override
public void setAlpha(int alpha) {
    // do nothing
}

@Override
public void setColorFilter(ColorFilter cf) {
    // do nothing
}

@Override
public int getOpacity() {
    return PixelFormat.UNKNOWN;
}
}

更多信息请访问此网站visit here

答案 2 :(得分:1)

你在这里错过的是如下,

<?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content">
  <LinearLayout
      android:id="@+id/lnrButton"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:orientation="vertical"
     android:layout_marginBottom="4dp"
     android:layout_marginTop="4dp">
    <ImageView
       android:id="@android:id/icon"
       android:layout_gravity="center"
       android:layout_width="24dp"
       android:layout_height="24dp"
       android:scaleType="centerInside" />
    <TextView
       android:id="@android:id/text1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textColor="@drawable/tab_selector"
       android:ellipsize="end"
       android:textAllCaps="true"
       android:gravity="center"
       android:maxLines="2" />
 </LinearLayout>
 <TextView
       android:id="@+id/badgeCounter"
       android:layout_width="wrap_content"
       android:layout_height="20dp"
       android:alignRight = "@+id/lnrButton"
       android:alignTop = "@+id/lnrButton"
       android:minWidth="20dp"
       android:textAlignment="center"
       android:background="@drawable/count_background"
       android:textSize="15sp" />
 </RelativeLayout>

以下是你错过了

       android:alignRight = "@+id/lnrButton"
       android:alignTop = "@+id/lnrButton"

或者如果你想在图像上出现徽章,请删除所有LinearLayout并使其成为Relativelaout而不是lnrButton使用imageview id