android中进度条两边都是圆角的

发布于 2024-08-18 06:40:12 字数 3136 浏览 8 评论 0原文

我正在尝试在 android 中创建一个自定义进度条。我使用了以下 xml 文件(progress_bar_horizo​​ntal.xml):

<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@android:id/background">
   <shape>
    <corners android:radius="8dip" />
    <stroke android:width="2dip" android:color="#FFFF"/>
    <solid android:color="#FFFF"/>              
   </shape>
  </item>
  <item android:id="@android:id/secondaryProgress">
   <clip>
    <shape>
     <corners android:radius="8dip" />
     <stroke android:width="2dip" android:color="#FFFF"/>
     <solid android:color="#FF00"/> 
    </shape>
   </clip>
  </item>
  <item android:id="@android:id/progress">
   <clip>
    <shape>
     <corners android:radius="8dip" />
     <stroke android:width="2dip" android:color="#FFFF"/>
     <solid android:color="#FF00"/> 
    </shape>
   </clip>
  </item>
 </layer-list>

除了我希望进度条中的进度在两侧都圆整之外,一切都运行良好。上述代码使进度条在左侧圆角化,并在右侧简单地剪切(不圆角化)。可能是因为 Clip 标签。你能帮我一下吗?我应该更改什么才能使进度条中的进度在两侧四舍五入?

完整布局如下:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical">
  <LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical"
  android:background="@drawable/gradient_progress"
  android:padding="10dip"
  >
   <LinearLayout
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:orientation="horizontal"
   >
    <TextView
     android:id="@+id/progress_header"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textColor="#FF000000"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textStyle="bold"
     android:text="Uploading"               
    />
    <TextView
     android:id="@+id/progress_percent"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textColor="#FF000000"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textStyle="bold"
     android:text="55%"         
     android:paddingLeft="10dip"
    />      
   </LinearLayout>          
   <ProgressBar
    android:id="@+id/progress_bar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_gravity="center"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:progressDrawable="@drawable/progress_bar_horizontal"
    android:maxHeight="12dip"    
    android:minHeight="12dip"    
    android:max="100" 
   />
  </LinearLayout>
 </LinearLayout>

这是我努力的结果:链接文本

我希望红色条的右侧也有圆形边缘。 非常感谢您的评论。

I am trying to create a custom progress bar in android. I have used the following xml file for it (progress_bar_horizontal.xml):

<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@android:id/background">
   <shape>
    <corners android:radius="8dip" />
    <stroke android:width="2dip" android:color="#FFFF"/>
    <solid android:color="#FFFF"/>              
   </shape>
  </item>
  <item android:id="@android:id/secondaryProgress">
   <clip>
    <shape>
     <corners android:radius="8dip" />
     <stroke android:width="2dip" android:color="#FFFF"/>
     <solid android:color="#FF00"/> 
    </shape>
   </clip>
  </item>
  <item android:id="@android:id/progress">
   <clip>
    <shape>
     <corners android:radius="8dip" />
     <stroke android:width="2dip" android:color="#FFFF"/>
     <solid android:color="#FF00"/> 
    </shape>
   </clip>
  </item>
 </layer-list>

Everything works great apart from the fact I would like to have the progress in my progress bar rounded on both sides. The aforementioned code makes a progress bar to be rounded on the left hand side and simply cut (not rounded) on the right hand side. It is because of the clip tag probably. Could you please help me on that? What should i change to have the progress in my progress bar rounded on both sides?

The full layout goes below:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical">
  <LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical"
  android:background="@drawable/gradient_progress"
  android:padding="10dip"
  >
   <LinearLayout
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:orientation="horizontal"
   >
    <TextView
     android:id="@+id/progress_header"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textColor="#FF000000"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textStyle="bold"
     android:text="Uploading"               
    />
    <TextView
     android:id="@+id/progress_percent"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textColor="#FF000000"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textStyle="bold"
     android:text="55%"         
     android:paddingLeft="10dip"
    />      
   </LinearLayout>          
   <ProgressBar
    android:id="@+id/progress_bar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_gravity="center"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:progressDrawable="@drawable/progress_bar_horizontal"
    android:maxHeight="12dip"    
    android:minHeight="12dip"    
    android:max="100" 
   />
  </LinearLayout>
 </LinearLayout>

Here is the result of my effort: link text

I would like the red bar to have rounded edges on the right hand side as well.
Thank you so much for your comments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

权谋诡计 2024-08-25 06:40:12

下面是时代更新的答案:

Android源码使用Patch 9文件来实现效果:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/res/res/drawable/progress_horizo​​ntal_holo_dark.xml /

因此,从您的布局 xml 开始:

<ProgressBar
    android:id="@+id/custom_progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:indeterminateOnly="false"
    android:progressDrawable="@drawable/custom_progress_bar_horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="13"
    android:progress="33"
    android:secondaryProgress="66" />

您可以将其中的大部分内容移至样式 xml,但这不是重点。我们真正关心的是 android:progressDrawable="@drawable/custom_progress_bar_horizo​​ntal" - 这将允许我们指定我们自己的自定义进度条:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background"
          android:drawable="@android:drawable/custom_progress_bg" />
    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%"
               android:drawable="@android:drawable/custom_progress_secondary" />
    </item>
    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%"
               android:drawable="@android:drawable/custom_progress_primary" />
    </item>
</layer-list>

或者您不必使用 Patch 9你的背景 - 例如,这是一个带有 1dp 边框的简单白色背景:

<item android:id="@android:id/background">
    <shape>
        <corners android:radius="6.5dp" />

        <solid android:color="@android:color/white" />

        <stroke
            android:width="1dp"
            android:color="@android:color/darker_gray" />
    </shape>
</item>

Android Asset Studio 有一个很棒的工具可以帮助你生成 Patch 9 文件:
http://android-ui-utils.googlecode.com/hg/ asset-studio/dist/nine-patches.html

主要 xdpi png 示例,工具前有填充:
主进度条
工具前有填充的辅助 xdpi png 示例:
辅助进度条

最终输出:
自定义进度条

Here's an updated answer for the times:

The Android source code uses Patch 9 files to achieve the effect:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/res/res/drawable/progress_horizontal_holo_dark.xml/

So start in your layout xml:

<ProgressBar
    android:id="@+id/custom_progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:indeterminateOnly="false"
    android:progressDrawable="@drawable/custom_progress_bar_horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="13"
    android:progress="33"
    android:secondaryProgress="66" />

You can move a lot of this to a style xml but that's beside the point. What we really care about is android:progressDrawable="@drawable/custom_progress_bar_horizontal" - which is going to allow us to specify our own custom progress bars:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background"
          android:drawable="@android:drawable/custom_progress_bg" />
    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%"
               android:drawable="@android:drawable/custom_progress_secondary" />
    </item>
    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%"
               android:drawable="@android:drawable/custom_progress_primary" />
    </item>
</layer-list>

Or you don't have to use a Patch 9 for your background- for example here's a simple white background with a 1dp border:

<item android:id="@android:id/background">
    <shape>
        <corners android:radius="6.5dp" />

        <solid android:color="@android:color/white" />

        <stroke
            android:width="1dp"
            android:color="@android:color/darker_gray" />
    </shape>
</item>

Android Asset Studio has an awesome tool to help you generate Patch 9 files:
http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html

Example primary xdpi png with padding before the tool:
Primary progress bar
Example secondary xdpi png with padding before the tool:
Secondary progress bar

And the final output:
Custom progress bar

蓝咒 2024-08-25 06:40:12

只需将标签 更改为 ,如下所示:

<scale android:scaleWidth="100%">

Just change the label <clip> to <scale> like this:

<scale android:scaleWidth="100%">
像你 2024-08-25 06:40:12

您可以使用材质组件库提供的 LinearProgressIndicatorapp:trackCornerRadius 属性。

类似于:

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:indeterminate="true"
        app:indicatorSize="xxdp"
        app:trackCornerRadius="xdp"/>

在此处输入图像描述

注意:它至少需要版本1.3.0-alpha04

You can use the LinearProgressIndicator provided by the Material Components Library and the app:trackCornerRadius attribute.

Something like:

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:indeterminate="true"
        app:indicatorSize="xxdp"
        app:trackCornerRadius="xdp"/>

enter image description here

Note: it requires at least the version 1.3.0-alpha04.

念﹏祤嫣 2024-08-25 06:40:12

据我所知,这是不可能的。因为在内部 ClipDrawable (即剪辑标签)使用 canvas.clipRect() 剪切给定的形状/可绘制对象。顺便说一句,您可以从 此处 并根据进度级别剪辑特定路径。

As far as I know, this is not possible. Because internally ClipDrawable (i.e. clip tag) cuts the given shape/drawable using canvas.clipRect(). Btw, you can copy the ClipDrawable source from here and clip a particular path based on the progress level.

风渺 2024-08-25 06:40:12

为了解决当进度非常低时最终图形自身重叠的问题,我编写了 ProgressBar 类的扩展,它向进度条添加了固定的起始偏移量,而其他功能则正常。

只需调用“setMaxWithPercentOffset()”或“setMaxWithOffset()”,而不是“setMax()”,传入要添加为进度条起始偏移量的值。

如果有人在不需要开始偏移的情况下解决了这个问题,请告诉我!

/**
 * This progress bar can be used when the progress bar end graphics are styled in some way.
 * In this case, the progress bar must always have a small percentage of progress, otherwise
 * the styled ends of the progress overlap each other.
 *
 */
public class EndStyledProgressBar extends ProgressBar {
    private static final int DEFAULT_START_OFFSET_PERCENT = 5;

    private int mStartOffset;
    private int mRealMax;

    public EndStyledProgressBar(Context context) {
        super(context);
        commonConstructor();
    }

    public EndStyledProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        commonConstructor();
    }

    public EndStyledProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        commonConstructor();
    }

    private void commonConstructor() {
        mRealMax = super.getMax();
        mStartOffset = 0;

        setMaxWithPercentOffset(DEFAULT_START_OFFSET_PERCENT, mRealMax);

        super.setProgress(super.getProgress() + mStartOffset);
        super.setSecondaryProgress(super.getSecondaryProgress() + mStartOffset);
    }

    public void setProgress(int progress) {
        super.setProgress(progress + mStartOffset);
    }

    public void setSecondaryProgress(int secondaryProgress) {
        super.setSecondaryProgress(secondaryProgress + mStartOffset);
    }

    public int getProgress() {
        int realProgress = super.getProgress();
        return isIndeterminate() ? 0 : (realProgress - mStartOffset);
    }


    public  int getSecondaryProgress() {
        int realSecondaryProgress = super.getSecondaryProgress();
        return isIndeterminate() ? 0 : (realSecondaryProgress - mStartOffset);
    }

    public int getMax() {
        return mRealMax;
    }


    /**
     * Don't call this, instead call setMaxWithPercentOffset() or setStartOffsetInPercent()
     *
     * @param max
     */
    public void setMax(int max) {
        super.setMax(max);
    }

    /**
     * Sets a new max with a start offset (in percent) included.
     *
     * @param startOffsetInPercent start offset for the progress bar to avoid graphic errors.
     */
    public void setMaxWithPercentOffset(int startOffsetInPercent, int max) {
        mRealMax = max;
        int startOffset = (mRealMax * startOffsetInPercent) / 100;

        setMaxWithOffset(startOffset, max);
    }

    /**
     * Sets a new max with a start offset included.
     *
     * @param startOffset start offset for the progress bar to avoid graphic errors.
     */
    public void setMaxWithOffset(int startOffset, int max) {
        mRealMax = max;

        super.setMax(startOffset + max);

        setStartOffset(startOffset);

        super.setMax(startOffset + max);
    }


    /**
     * Sets a new start offset different from the default of 5%
     *
     * @param startOffset start offset for the progress bar to avoid graphic errors.
     */
    private void setStartOffset(int startOffset) {
        int newStartOffset = startOffset;

        // Ensure the start offset is not outside the range of the progress bar
        if (newStartOffset < 0) newStartOffset = 0;
        if (newStartOffset >= super.getMax()) newStartOffset = super.getMax();

        // Apply the start offset difference
        if (mStartOffset != newStartOffset) {
            int diff = newStartOffset - mStartOffset;
            super.setMax(super.getMax() + diff);
            super.setProgress(super.getProgress() + diff);
            super.setSecondaryProgress(super.getSecondaryProgress() + diff);
            mStartOffset = newStartOffset;
        }
    }
}

In order to solve the problem where the end graphics overlap themselves when the progress is very low, I've written an extension to the ProgressBar class that adds a fixed start offset to the progress bar, while otherwise functioning as normal.

Just call 'setMaxWithPercentOffset()' or 'setMaxWithOffset()' rather than 'setMax()' passing in the value you want to add as a start offset to the progress bar.

If anyone has solved this problem without requiring the start offset let me know!

/**
 * This progress bar can be used when the progress bar end graphics are styled in some way.
 * In this case, the progress bar must always have a small percentage of progress, otherwise
 * the styled ends of the progress overlap each other.
 *
 */
public class EndStyledProgressBar extends ProgressBar {
    private static final int DEFAULT_START_OFFSET_PERCENT = 5;

    private int mStartOffset;
    private int mRealMax;

    public EndStyledProgressBar(Context context) {
        super(context);
        commonConstructor();
    }

    public EndStyledProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        commonConstructor();
    }

    public EndStyledProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        commonConstructor();
    }

    private void commonConstructor() {
        mRealMax = super.getMax();
        mStartOffset = 0;

        setMaxWithPercentOffset(DEFAULT_START_OFFSET_PERCENT, mRealMax);

        super.setProgress(super.getProgress() + mStartOffset);
        super.setSecondaryProgress(super.getSecondaryProgress() + mStartOffset);
    }

    public void setProgress(int progress) {
        super.setProgress(progress + mStartOffset);
    }

    public void setSecondaryProgress(int secondaryProgress) {
        super.setSecondaryProgress(secondaryProgress + mStartOffset);
    }

    public int getProgress() {
        int realProgress = super.getProgress();
        return isIndeterminate() ? 0 : (realProgress - mStartOffset);
    }


    public  int getSecondaryProgress() {
        int realSecondaryProgress = super.getSecondaryProgress();
        return isIndeterminate() ? 0 : (realSecondaryProgress - mStartOffset);
    }

    public int getMax() {
        return mRealMax;
    }


    /**
     * Don't call this, instead call setMaxWithPercentOffset() or setStartOffsetInPercent()
     *
     * @param max
     */
    public void setMax(int max) {
        super.setMax(max);
    }

    /**
     * Sets a new max with a start offset (in percent) included.
     *
     * @param startOffsetInPercent start offset for the progress bar to avoid graphic errors.
     */
    public void setMaxWithPercentOffset(int startOffsetInPercent, int max) {
        mRealMax = max;
        int startOffset = (mRealMax * startOffsetInPercent) / 100;

        setMaxWithOffset(startOffset, max);
    }

    /**
     * Sets a new max with a start offset included.
     *
     * @param startOffset start offset for the progress bar to avoid graphic errors.
     */
    public void setMaxWithOffset(int startOffset, int max) {
        mRealMax = max;

        super.setMax(startOffset + max);

        setStartOffset(startOffset);

        super.setMax(startOffset + max);
    }


    /**
     * Sets a new start offset different from the default of 5%
     *
     * @param startOffset start offset for the progress bar to avoid graphic errors.
     */
    private void setStartOffset(int startOffset) {
        int newStartOffset = startOffset;

        // Ensure the start offset is not outside the range of the progress bar
        if (newStartOffset < 0) newStartOffset = 0;
        if (newStartOffset >= super.getMax()) newStartOffset = super.getMax();

        // Apply the start offset difference
        if (mStartOffset != newStartOffset) {
            int diff = newStartOffset - mStartOffset;
            super.setMax(super.getMax() + diff);
            super.setProgress(super.getProgress() + diff);
            super.setSecondaryProgress(super.getSecondaryProgress() + diff);
            mStartOffset = newStartOffset;
        }
    }
}
云巢 2024-08-25 06:40:12

最终圆形双方进度条(不含 9 补丁)为:
android:progressDrawable="@drawable/progress_horizo​​ntal_green"

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/progress">
    <scale android:scaleWidth="100%">
        <shape>
            <corners android:radius="5dip"/>
            <solid android:color="#33FF33"/>
        </shape>
    </scale>
</item>

Final rounded both sides progress bar without 9-patch is:
android:progressDrawable="@drawable/progress_horizontal_green"

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/progress">
    <scale android:scaleWidth="100%">
        <shape>
            <corners android:radius="5dip"/>
            <solid android:color="#33FF33"/>
        </shape>
    </scale>
</item>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文