如何创建完整的圆形 LinearLayout 或 RelativeLayout

sag*_*uri 2 android android-layout

我正在尝试创建一个完整的圆形布局,以便我在该布局中放置任何内容。该内容应该在圆圈内。这怎么可能?我尝试了以下方法。但形状并非一直是圆形的。有时它会根据空间变成椭圆形。如何始终保持布局循环,内容应该在里面?

<LinearLayout
            android:id="@+id/zodiac_Layout"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:orientation="vertical"
            android:background="@drawable/circular_background">

            <ImageView
                android:id="@+id/zodiac_img"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginRight="2dp"
                android:adjustViewBounds="true"
                android:src="@drawable/sunrise" />

            <TextView
                android:id="@+id/zodiac_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="5dp"
                android:text="@string/na"
                android:textColor="#fff"
                android:textSize="@dimen/nakshatra_text_size" />
        </LinearLayout>
Run Code Online (Sandbox Code Playgroud)

这是 circular_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#50514F"/>
    <size android:width="5dp"
        android:height="5dp"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

如果我使ImageView match_parent. 它来自布局的圆形。我希望沿着布局的圆形裁剪内容。

Xen*_*ion 6

由于我们在评论中聊天。现在我知道你真正想要的是你的ImageViewTextView. 因此,经过专门的工作,我决定形成解决方案,该解决方案将产生如下图所示的输出:

在这张图片中.
不要担心 textView 你可以把它放在任何地方。甚至在图像的顶部!并改变它的大小!

首先,您必须知道在这方面没有默认实现,这意味着在 android 中没有提供圆形裁剪视图的默认 View 类。因此,这里是使用XML解决此技巧的两种替代方法!

第一个替代方案(最佳选项)
我们将使用一个FrameLayout在彼此之上添加视图的布局。这意味着如果你把第一个然后第二个将在第一个之上等等。

要求

  • 为了在圆形视图中很好地适应图像,它应该是SQUARE这只是合乎逻辑的),因此您需要将宽度和高度设置为相等的值。

  • 我们需要一个带有笔划的圆形(这个想法是把它放在一个计算良好的视图大小之上!

在您的drawable文件夹中创建一个名为circular_image_crop.xml. 并粘贴代码(不要担心稍后会描述!)不要忘记阅读其中的注释:

<?xml version="1.0" encoding="utf-8"?>
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">
  <solid android:color="#00ffffff"/>
   <!--The above colour is completely transparent!-->
  <stroke android:width="20dp" android:color="#ec407a" />
  <size android:width="140dp" android:height="140dp"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

制作该drawable文件后,我们将必须制作我们的FrameLayout此框架布局不是任何视图的根视图,只需将其复制到您想要显示此布局的任何视图中)继续粘贴下面的代码(我们稍后会解释!)再次阅读其中的评论:

<FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ec407a">

        <!-- This is our framelayout! Notice our background color is the same as the one in the stroke of our drawable. Also this is your image view notice the it has width and height similar (square) do use match parent or wrap content just define a square and views will be position by adjust view bounds true-->

        <ImageView
            android:id="@+id/image_view_user_profile_image"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/your_image_description"
            android:src="@drawable/your_image" />

        <!-- Ooh here we have another image! This is an image just for displaying our drawable and crop our image (how?? dont worry!) -->

        <ImageView
            android:layout_width="140dp"
            android:layout_height="140dp"
            android:layout_gravity="center_horizontal"
            android:contentDescription="@string/also_your_image_description_if_any"
            android:src="@drawable/circular_image_crop" />
        <!--This text view we almost forget here it is!-->
        <TextView
            android:id="@+id/your_text_view_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="125dp"
            android:gravity="center"
            android:text="John Nanai Noni"
            android:textColor="#ffffff"
            android:textSize="16sp"
            android:textStyle="bold" />
    </FrameLayout>
Run Code Online (Sandbox Code Playgroud)

它是如何工作的和自定义的!???
好消息是我们使用了我们的框架布局并将我们的真实视图定位在水平中心(方形图像)。我们制作了drawable一个圆形,并且在中心有一个圆形孔(空间),高度和我们的图片相匹配。最后,我们添加我们的 textview 并放在所有这些之上,但在底部(它不应该遮住图像对吗?)。

因此,我们可以理解这一点的方式是将以下图像视为所需内容的轮廓。(不要认为它很复杂):

样本1

所以从那里我们可以看到它是如何在圆形裁剪等中间的图像上进行的

样本2

下一阶段:

样本3

从那里我们可以将相同的背景颜色应用到我们的整个布局 (FrameLayout) 以隐藏圆形的东西并留下我们自己的可见空间。

样本 4

是的,我们已经完成了我们的布局!定制呢。

自定义

对于颜色,您可以将自己的颜色放置在 FrameLayout 背景以及可绘制对象的笔划中的任何位置。但永远不要改变<solid>颜色,它应该总是完全透明的。
为了自定义圆形裁剪的半径,让我们深入研究其数学公式来计算图像的覆盖范围!

数学

让您的图像widthheight记住图像是方形的)为x dps。那么你的值drawable

行程= 0.2071 * x

尺寸(高度和宽度)=笔画 + x

你可以用 2 或 3 dps 来消除截断错误!

其实背后的数学是基于下面的公式。如果您感兴趣如何评论下面的公式,则该公式有效:
简单的方法!

第二个

替代方案我认为对于关心圆形视图之间的空间的人来说,另一个替代方案是ImageView将 CardView 置于内部并使拐角半径half与 CardView 的大小相同,例如此代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="280dp"
    android:layout_height="280dp"
    android:layout_gravity="center_horizontal"
    android:layout_margin="30dp"
    app:cardCornerRadius="140dp"
    app:cardElevation="12dp">

    <ImageView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:adjustViewBounds="true"
        android:src="@drawable/login_back_ground" />

 </android.support.v7.widget.CardView>
Run Code Online (Sandbox Code Playgroud)

这是我在 android Studio 中得到的输出。我也不能保证这在各种设备中会是什么样子,尤其是旧设备!

卡片视图图像

结论

两种方法都是好的和有用的。了解两者甚至可以导致更多的自定义,例如使用第一个替代方案和第二个选项来实现自定义,例如添加圆形图像的高度。但是第一种方法适合日常使用的次数,并且它也为所有Android设备带来了同等的体验。

我希望这甚至可以帮助将来可能遇到相同问题的用户。