Androidで角が丸いListViewを作成するにはどうすればよいですか?


回答:


371

これを行う1つの方法を次に示します(Androidのドキュメントに感謝します!):

以下をファイル(たとえばcustomshape.xml)に追加し、それを(res / drawable / customshape.xml)に配置します。

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
     android:shape="rectangle"> 
     <gradient 
         android:startColor="#SomeGradientBeginColor"
         android:endColor="#SomeGradientEndColor" 
         android:angle="270"/> 

    <corners 
         android:bottomRightRadius="7dp" 
         android:bottomLeftRadius="7dp" 
         android:topLeftRadius="7dp" 
         android:topRightRadius="7dp"/> 
</shape> 

このファイルの作成が完了したら、次のいずれかの方法で背景を設定します。

コードを通じて: listView.setBackgroundResource(R.drawable.customshape);

XMLを使用して、次の属性をコンテナに追加するだけです(例:LinearLayoutまたは任意のフィールド)。

android:background="@drawable/customshape"

誰かがそれが便利だと思うことを願っています...


2
素晴らしいヒントをありがとう。ちょうどFYI、コピー&ペーストは、言ってくれ実行時例外を与えた「XmlPullParserException:バイナリXMLファイルライン#4 <グラデーション>タグが45の倍数に『角度』属性が必要です」..簡単に270に角度を変えることで改善
allclaws

修正してくれてありがとう...しかし、それがなぜ起こり得るのかはわかりません。特定の理由を見つけましたか?
レジェンド

@teedyay:Anytime pal :)
レジェンド

1
allclawsと同じように、角度は45の倍数にする必要があります: "XmlPullParserException:Binary XML file line#4 <gradient> tag require 'angle' attribute to be a multiple of 45"
Youssef

29
ただし、選択ハイライト表示ではうまく機能しません。上部または下部のアイテムを選択すると、色付きの背景は長方形になり、角の丸い背景の上に描画されます。
Kris Van Bael、2011

56

これでうまくいきましたが、背景色全体も削除されました。私は境界線だけを行う方法を探していて、そのXMLレイアウトコードをこれに置き換えるだけでよかったです。

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="4dp" android:color="#FF00FF00" />
    <padding android:left="7dp" android:top="7dp"
            android:right="7dp" android:bottom="7dp" />
    <corners android:radius="4dp" />
</shape> 

また、この回答も
ご覧

12

@ kris-van-bael

選択時に背景の長方形が表示される最上行と最下行の選択ハイライトに問題がある場合は、リストビューのセレクターを透明色に設定する必要があります。

listView.setSelector(R.color.transparent);

color.xmlに以下を追加するだけです-

<color name="transparent">#00000000</color>

5
うまくいきませんでした。ただし、次の行を追加したところ、android:cacheColorHint="@android:color/transparent"
削除されまし

1
これにより、選択の問題が確実に修正されました-ありがとう!独自の色を作成する代わりに、セレクタの色としてandroid.R.color.transparentを使用することもできます。
greg7gkb 2012年

3
プログラムで行う代わりに、これをXMLレイアウトのListViewに追加して、選択色を非表示にします。android:listSelector = "#00000000"
Elad Nava

@alvinsリストビューアイテムのような強調表示のためにレイアウトを選択可能にする方法はありますか?
Bharat Dodeja 2013年

listSelectorに不透明な色を使用したい場合はどうすればよいですか?
Suitianshi 2014

3

著者のおかげで、他の答えは非常に役に立ちます!

しかし、選択時にアイテムを強調表示するとき、@ alvins @bharat dojehaの強調表示を無効にするのではなく、長方形をカスタマイズする方法がわかりませんでした。

以下は、同じ形状で選択されたときに輪郭がなく、薄い灰色の丸みのあるリストビューアイテムコンテナーを作成するのに役立ちます。

xmlには、たとえば(res / drawable / customshape.xml内)などのセレクターを含める必要があります。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <stroke android:width="8dp" android:color="@android:color/transparent" />
        <padding android:left="14dp" android:top="14dp"
                android:right="14dp" android:bottom="14dp" />
        <corners android:radius="10dp" />
        <gradient 
             android:startColor="@android:color/background_light"
             android:endColor="@android:color/transparent" 
             android:angle="225"/> 
    </shape>
</item>
<item android:state_pressed="false">
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <stroke android:width="8dp" android:color="@android:color/transparent" />
        <padding android:left="14dp" android:top="14dp"
                android:right="14dp" android:bottom="14dp" />
        <corners android:radius="10dp" />
        <gradient 
             android:startColor="@android:color/darker_gray"
             android:endColor="@android:color/transparent" 
             android:angle="225"/> 
    </shape>        
</item>

次に、リストアダプターを実装し、getViewメソッドをオーバーライドして、カスタムセレクターを背景として設定する必要があります。

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //snip
        convertView.setBackgroundResource(R.drawable.customshape);
        //snip
    }

また、onCreateなどでデフォルトのセレクター長方形を「隠す」必要もあります(アイテム間の薄い灰色の仕切り線も非表示にします)。

listView.setSelector(android.R.color.transparent);
listview.setDivider(null);

このアプローチは、さまざまな選択状態を持つListViewItemだけでなく、ドローアブルの一般的なソリューションを解決します。



2

選択のさらに別の解決策は、リストの最初と最後の項目の問題を強調します。

リストの背景の上と下に、半径以上のパディングを追加します。これにより、選択の強調表示がコーナーカーブと重ならないようになります。

これは、不透明な選択の強調表示が必要な場合に最も簡単なソリューションです。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="@color/listbg" />
    <stroke
        android:width="2dip"
        android:color="#D5D5D5" />
    <corners android:radius="10dip" />

    <!-- Make sure bottom and top padding match corner radius -->
    <padding
        android:bottom="10dip"
        android:left="2dip"
        android:right="2dip"
        android:top="10dip" />
</shape>


1

これは私にとって非常に便利でした。あなたがあなた自身のものを使っているなら、丸みを帯びた角を完全に強調するために別の回避策を提案したいと思いますCustomAdapter

XMLファイルの定義

まず、ドローアブルフォルダー内に移動し、4つの異なる形状を作成します。

  • shape_top

    <gradient
        android:startColor="#ffffff"
        android:endColor="#ffffff"
        android:angle="270"/>
    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"/>

  • shape_normal

    <gradient
        android:startColor="#ffffff"
        android:endColor="#ffffff"
        android:angle="270"/>
    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"/>

  • shape_bottom

    <gradient
        android:startColor="#ffffff"
        android:endColor="#ffffff"
        android:angle="270"/>
    <corners
        android:bottomRightRadius="10dp"
        android:bottomRightRadius="10dp"/>

  • shape_rounded

    <gradient
        android:startColor="#ffffff"
        android:endColor="#ffffff"
        android:angle="270"/>
    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"
        android:bottomRightRadius="10dp"
        android:bottomRightRadius="10dp"/>

次に、形状ごとに異なる行レイアウトを作成しますshape_top

  • プログラムで背景を変更することもできます。

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="10dp"
        android:fontFamily="sans-serif-light"
        android:text="TextView"
        android:textSize="22dp" />
    
    <TextView
        android:id="@+id/txtValue1"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:textSize="22dp"
        android:layout_gravity="right|center"
        android:gravity="center|right"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="35dp"
        android:text="Fix"
        android:scaleType="fitEnd" />

そして、各定形リストのセレクターを定義しますshape_top

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Selected Item -->

    <item android:state_selected="true"
        android:drawable="@drawable/shape_top" />
    <item android:state_activated="true"
        android:drawable="@drawable/shape_top" />

    <!-- Default Item -->
    <item android:state_selected="false"
        android:drawable="@android:color/transparent" />
</selector>

CustomAdapterを変更する

最後に、内のレイアウトオプションを定義しますCustomAdapter

if(position==0)
{
 convertView = mInflater.inflate(R.layout.list_layout_top, null);
}
else
{
 convertView = mInflater.inflate(R.layout.list_layout_normal, null);
}

if(position==getCount()-1)
{
convertView = mInflater.inflate(R.layout.list_layout_bottom, null);
}

if(getCount()==1)
{
convertView = mInflater.inflate(R.layout.list_layout_unique, null);
}

これで完了です。


1

ボーダーを作成するには、描画可能なフォルダーにソリッドとコーナーのプロパティを持つ別のxmlファイルを作成し、バックグラウンドで呼び出す必要があります


0

他のビューの上にレイアウトし、背景と同じ色で4つの小さなコーナーを描画するカスタムビューを使用しています。これは、ビューの内容が何であっても機能し、多くのメモリを割り当てません。

public class RoundedCornersView extends View {
    private float mRadius;
    private int mColor = Color.WHITE;
    private Paint mPaint;
    private Path mPath;

    public RoundedCornersView(Context context) {
        super(context);
        init();
    }

    public RoundedCornersView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.RoundedCornersView,
                0, 0);

        try {
            setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
            setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
        } finally {
            a.recycle();
        }
    }

    private void init() {
        setColor(mColor);
        setRadius(mRadius);
    }

    private void setColor(int color) {
        mColor = color;
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        invalidate();
    }

    private void setRadius(float radius) {
        mRadius = radius;
        RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
        mPath = new Path();
        mPath.moveTo(0,0);
        mPath.lineTo(0, mRadius);
        mPath.arcTo(r, 180, 90);
        mPath.lineTo(0,0);
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        /*Paint paint = new Paint();
        paint.setColor(Color.RED);
        canvas.drawRect(0, 0, mRadius, mRadius, paint);*/

        int w = getWidth();
        int h = getHeight();
        canvas.drawPath(mPath, mPaint);
        canvas.save();
        canvas.translate(w, 0);
        canvas.rotate(90);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.save();
        canvas.translate(w, h);
        canvas.rotate(180);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.translate(0, h);
        canvas.rotate(270);
        canvas.drawPath(mPath, mPaint);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.