如何从底部设计一个圆形视图?

4
我正在尝试设计一个底部是圆形的视图,请参见以下图片: enter image description here 我已经尝试了不同的设计方法,如XML和编程方式,但都没有成功。使用XML代码可以从底部做出圆形,但是使用任何图像或横幅滑块(如图所示)时,整个视图会被占用。
目前我正在使用以下XML代码:
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:background="@drawable/bottom_radius"
    android:orientation="vertical">

    <ss.com.bannerslider.views.BannerSlider
        android:id="@+id/bannerSlider"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

还有 bottom_radius.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="oval">
        <solid android:color="@color/colorPrimaryDark" />
    </shape>
</item>
<item
    android:bottom="4dp"
    android:left="0dp"
    android:right="0dp"
    android:top="0dp">
    <shape android:shape="oval">
        <solid android:color="@android:color/white" />
    </shape>
</item>

输出结果以XML格式呈现,如下图: enter image description here 引用块中说到,XML输出结果看起来很好,符合预期。但是当在手机或模拟器上运行程序并查看输出结果时,效果如下图: enter image description here 请提供解决方案,以便我可以设计我想要的界面。非常感谢您的帮助。

好的,我尝试了你的代码,它没有弯曲。 - Abdul Kawee
快速而不太规范的方法是将白色部分放在圆形图像下方的矩形图像上方。这将导致过度绘制(因此不是最佳选择),但应该可以工作。 - Henry
@Henry,请给我提供解决方案,因为我已经花了很多时间在这上面,我该如何实现这个东西。 - Pushpendra
3个回答

1
android:background="@drawable/bottom_radius"放在图像上,而不是linearlayout

Kurusu,感谢您给我提出建议,但是它并没有起作用。 - Pushpendra

0

制作一个可绘制文件。

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <stroke android:width="1dp"
        android:color="@color/colorPrimary"
        />
    <padding android:left="1dp"
        android:top="1dp"
        android:right="1dp"
        android:bottom="1dp"
        />
    <corners android:bottomRightRadius="150dp"
        android:bottomLeftRadius="150dp"
        />
</shape>

然后将其设置为主布局的背景


0

请参考 PorterDuff.Mode 类。它允许开发者以多种不同的方式组合两个位图。以下我们将使用 Porter-Duff 模式 PorterDuff.Mode.DST_IN

以下是一个简短的演示,展示如何生成您想要的结果。首先,这是结果:

enter image description here

我们将使用下面的图像,使用Porter-Duff模式PorterDuff.Mode.DST_IN来裁剪照片到我们想要的形状。一旦应用了Porter-Duff模式,非透明区域将保留在目标位图(我们的照片)中,与下面图像的透明像素对应的照片像素将被丢弃。

enter image description here

现在照片已经被裁剪,我们将使用下面的图像应用黄色边框。(上面显示的裁剪位图中的黄色边框实际上并没有被使用。重要的是黄色区域所有像素的 alpha 值都为 1.0。)这个图像与之前的图像具有相同的尺寸,但透明区域还包括黄色弧线上方的区域。这个可绘制对象将简单地绘制在图像的顶部。

enter image description here

这里是代码:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView topImage = findViewById(R.id.bottomImage);
        topImage.setImageBitmap(cropAndOverlay(topImage, R.drawable.smile,
                                               R.drawable.smile_transparent));
    }

    private Bitmap cropAndOverlay(@NonNull ImageView imageView,
                                  @DrawableRes int cropId, @DrawableRes int overlayId) {
        // Get the bitmap for the current image.
        Bitmap dst = ((BitmapDrawable) imageView.getDrawable()).getBitmap();

        // Get the cropping image. This is the Porter-Duff source image.
        Bitmap src = Bitmap.createBitmap(dst.getWidth(), dst.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas resultCanvas = new Canvas(src);
        Drawable drawable = ResourcesCompat.getDrawable(getResources(), cropId, null);
        drawable.setBounds(0, 0, resultCanvas.getWidth(), resultCanvas.getHeight());
        drawable.draw(resultCanvas);

        // Combine the source with the destination bitmap while applying the Porter-Duff mode.
        Bitmap resultBitmap = getPorterDuffBitmap(dst, src, PorterDuff.Mode.DST_IN);
        resultCanvas.setBitmap(resultBitmap);

        // Place the overlay image on the bitmap.
        drawable = ResourcesCompat.getDrawable(getResources(), overlayId, null);
        drawable.setBounds(0, 0, resultBitmap.getWidth(), resultBitmap.getHeight());
        drawable.draw(resultCanvas);
        dst.recycle();
        return resultBitmap;
    }

    private Bitmap getPorterDuffBitmap(Bitmap dst, Bitmap src, PorterDuff.Mode mode) {
        Bitmap bitmap =
            Bitmap.createBitmap(dst.getWidth(), dst.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        // Draw the original bitmap (DST)
        canvas.drawBitmap(dst, 0, 0, null);

        // Draw the mask (SRC) with the specified Porter-Duff mode
        Paint maskPaint = new Paint();
        maskPaint.setXfermode(new PorterDuffXfermode(mode));
        canvas.drawBitmap(src, 0, 0, maskPaint);

        return bitmap;
    }
}

还有XML:

activity_main.xml

<LinearLayout 
    android:id="@+id/mainLayout"
    android:background="#b1a8a8"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/bottomImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:src="@drawable/photo" />

</LinearLayout>

我在主活动中介绍了这个,但是这种技术可能更适用于自定义视图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接