zoukankan      html  css  js  c++  java
  • android 边框圆角

    设置边框圆角可以在drawable目录里定义一个xml

    [xhtml] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <shape xmlns:android="http://schemas.android.com/apk/res/android">    
    3.     <solid android:color="#000000" />    
    4.     <corners android:topLeftRadius="10dp"   
    5.             android:topRightRadius="10dp"    
    6.             android:bottomRightRadius="10dp"   
    7.             android:bottomLeftRadius="10dp"/>    
    8. </shape>    

    解释: solid的表示填充颜色,为了简单,这里用的是黑色。

              而corners则是表示圆角,注意的是这里bottomRightRadius是左下角而不是右下角,bottomLeftRadius右下角。

    当然上面的效果也可以像下面一样设置,如下:

    [c-sharp] view plaincopy
    1. <corners android:radius="5dp" />   

     

    如果想引用这个xml,只需要@drawable/corners_bg.xml即可

    [xhtml] view plaincopy
    1. android:background="@drawable/corners_bg"    

     

    具体步骤如下:

    第一步:

    在drawable里面定义一个名为corners_bg.xml

    /CornerDemo/res/drawable-mdpi/corners_bg.xml

    [xhtml] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <shape xmlns:android="http://schemas.android.com/apk/res/android">    
    3.     <solid android:color="#000000" />    
    4.     <corners android:topLeftRadius="10dp"   
    5.             android:topRightRadius="10dp"    
    6.             android:bottomRightRadius="10dp"   
    7.             android:bottomLeftRadius="10dp"/>    
    8. </shape>   

     

    第二步:

    /CornerDemo/res/layout/main.xml

    [xhtml] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:orientation="vertical"  
    4.     android:layout_width="fill_parent"  
    5.     android:layout_height="fill_parent"  
    6.     android:background="#FFFFFF"  
    7.     >  
    8.     <RelativeLayout      
    9.         android:id="@+id/login_div"    
    10.         android:layout_width="fill_parent"    
    11.         android:layout_height="150dip"    
    12.         android:padding="15dip"             
    13.         android:layout_margin="15dip"      
    14.         android:background="@drawable/corners_bg"    
    15.     >     
    16.     </RelativeLayout>    
    17.   
    18. </LinearLayout>  

     

    效果图如下:

    2.1 基本的圆角、边框

    Android除了支持原始的图片资源外,比较棒的一点就是可以用XML文件定义一些简单的图形。这有点像web的CSS,不过相比CSS3,Android的xml实现还没那么强大,例如,边框要么四周都有,要么四周都没有(我们将在后面讨论这事)。xml drawable的传送门在这里

    要画一个带灰色边框和圆角的图形很容易,在drawable资源目录下添加一个xml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    <?xml version="1.0" encoding="utf-8"?>
    <!-- shape如果不声明形状则默认为正方形 -->
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <corners android:radius="5.0dp" />
        <!-- 圆角,你也可以对不同的角设置不同的数值 -->
        <solid android:color="#FFFFFF" />
        <!-- 形状的填充色 -->
        <stroke
            android:width="1dp"
            android:color="#CCCCCC" />
        <!-- 边框宽度和颜色 -->
    </shape>
    

    在你需要用到这东西的地方如某个View下,设置background就行了。

    2.2 “自由的边框“

    当前版本的Android SDK并没有给stroke提供bottom、left、right之类的属性,也就是说你无法通过它来让长方形的边框少于4条。啊,真是太遗憾了。怎么办呢?有人想到了对Layer List hack。 在StackOverflow上有不少这样的把戏

    为了实现只有left,right和top边框,我们可以这么写:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
        <item>
            <shape android:shape="rectangle" >
                <stroke
                    android:width="1dp"
                    android:color="@color/card_stroke" />
            </shape>
        </item>
        <item
            android:left="2dp"
            android:right="2dp"
            android:top="2dp">
            <!-- 在实际使用中我发现1dp达不到显示效果,而2dp正好可以显示边框 -->
            <shape android:shape="rectangle" >
                <solid android:color="@color/solid_white" />
            </shape>
        </item>
    </layer-list>
    

    原理差不多是这样:

    诡异的是理论上只要偏移量只要1dp就能显示1dp宽带边框了,但我在listview里实验了一下发现不行,换成2dp方可。有同学能解释解释么?

    如果要给图形加上圆角,只需要给每个shape加上

    1
    2
    3
    
    <corners
      android:topLeftRadius="5.0dip"
      android:topRightRadius="5.0dip" />
    

    值得注意的是,两个shape的radius在设置的时候请确保前面的图层不会把后面的挡住。

    3 小结

    要在Android中实现圆角和边框,比较简单的方法:图片、XML差不多就是这么用的啦。此外还有用Java代码调用draw方法画出来的,不过我没有研究过。 他们各有各的优点啦。用图片,能控制的东西更多,用代码修改起来比较另过。 最后要说的是两个方法的效率。在这个问题上,我留有疑问,没有做过专门的比较。但直观的感受是……好吧,没什么感受。

     

    Android控件大杂烩

    一直很希望能找到一个介绍各种Android UI pattern的网站,现在这里有一个。要是再完整一点,整理好一点那就更完美了。

    吾记得国人做过一个iOS的,有兴趣的同学去查查。

    四、带圆角的ListView

    圆角流行很久了,给ListView加上圆角会很酷。例如下面这个样子。

    实现方法有好几种:

    1. 给ListView整体设置一个带圆角的background

    在XML文件里你或许会这么做

    1
    
    android:background = "@drawable/bg_list"
    

    bg_list便是你定义的可以自适应大小的圆角图。具体做法你可以参看我的Android开发笔记——圆角和边框们

    这是我们最容易想到的一种解决方案。在很多时候它能起到作用。

    但是要应对上面的那种样子好像不太容易哦,怎么让scroll跑外面去?listview是占整个屏幕的宽度还是要做一个margin?

    唔,想来想去,好像只能这么干。

    等你实际运行一下你就发现——坑爹了。这个listview的background就和一个相框一样,而不是我们想要的那种:让整个list看上去像带圆角的卡片。此外,你的scroll也不是在屏幕的边缘,而是随listview过去了。当然,你可以在listview外面加一个ScrollLayout,但请相信我,那样还是起不了什么大作用。

    所以,这个解决方案适合什么情况呢? 当你需要做一个内部能滑动的带圆角的框体

    2. 给ListView设置padding,给每一个条目分别设置background

    我曾逆向工程Twitter for Android 想看看它们是怎么实现这样的卡片ListView的。我拿到了XML文件,我发现他们用了一个自定义的”CardView”,尼玛这得看Java源码。但反编译出来的结果甚是坑爹,我只能放弃。

    后来我自己研究了一下,找了个替代方案。

    基本思想是在ListView的Adapter的getView()函数里,根据position动态设置每个item的background。如,如果是第一个item,就给他一个顶部是圆角的背景。如果是当中的item,则给一个不带圆角的背景。如果是底部的item,就给一个底部带圆角的背景。

    实现代码片段如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    public class MyAdapter extends ArrayAdapter<String> {
        // other methods...
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            View view;
            if (convertView != null) {
                view = convertView;
                holder = (ViewHolder) view.getTag();
            } else {
                view = inflater.inflate(R.layout.list_item_view, parent, false);
                holder = new ViewHolder();
                holder.source = (TextView) view.findViewById(R.id.text);
                view.setTag(holder);
            }
            // 加载要显示的数据
            holder.text.setText(getItem(position));
            // 动态设置item的background
            if (position == 0) {
                holder.layout.setBackgroundResource(R.drawable.bg_list_row_top_selector);
            } else if(position == getCount() -1){
                holder.layout.setBackgroundResource(R.drawable.bg_list_row_bottom_selector);
            }else{
                holder.layout.setBackgroundResource(R.drawable.bg_list_row_middle_selector);
            }
            return view;
        }
        private static class ViewHolder {
            RelativeLayout layout;
            TextView text;          //比如我们的item里只有一个TextView
        }
    }
    

    每个item 背景的selector,如顶部item的背景

    1
    2
    3
    4
    5
    6
    7
    
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/bg_list_row_top_pressed" android:state_pressed="true"/>
        <item android:drawable="@drawable/bg_list_row_top_focused" android:state_focused="true"/>
        <item android:drawable="@drawable/bg_list_row_top_focused" android:state_selected="true"/>
        <item android:drawable="@drawable/bg_list_row_top"/>
    </selector>
    

    bg_list_row_top.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
        <item>
            <shape android:shape="rectangle" >
                <stroke
                    android:width="1dp"
                    android:color="#cccccc" />
                <corners
                    android:topLeftRadius="10.0dip"
                    android:topRightRadius="10.0dip" />
            </shape>
        </item>
        <item
            android:bottom="2dp"
            android:left="2dp"
            android:right="2dp"
            android:top="2dp">
            <shape android:shape="rectangle" >
                <solid android:color="#ffffff" />
                <corners
                    android:topLeftRadius="8.0dip"
                    android:topRightRadius="8.0dip" />
            </shape>
        </item>
    </layer-list>
    

    其他的几种状态如focused, pressed请自己脑补。

    你的ListView需要占满屏幕,并且可以做如下属性设置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="10.0dp"
        android:paddingRight="10.0dp"
        android:scrollbarStyle="outsideOverlay"
        android:background ="#ffe4e4e4"
        android:fadingEdge ="none"
        android:listSelector="#00000000"
        android:drawSelectorOnTop="false"
        android:cacheColorHint="#ffe4e4e4"
        android:divider="@null"
        android:dividerHeight="0.0px"
    />
    <!-- 让scroll块至于list最外面 -->
    

    五、题外话

  • 相关阅读:
    Codeforces 716C[数论][构造]
    HDU 5808[数位dp]
    Codeforces 611d [DP][字符串]
    Codeforces 404D [DP]
    HDU 5834 [树形dp]
    HDU 5521 [图论][最短路][建图灵感]
    矩阵
    kruskal 处理最短路 问题 A: 还是畅通工程
    Dijastra最短路 + 堆优化 模板
    CodeForces
  • 原文地址:https://www.cnblogs.com/fx2008/p/3138078.html
Copyright © 2011-2022 走看看