web-dev-qa-db-ja.com

Androidで角が丸いリストビューを作成するにはどうすればよいですか?

Androidで角が丸いリストビューを作成するにはどうすればよいですか?

175
Legend

これを行う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);

Through XML、次の属性をコンテナに追加します(例:LinearLayoutまたは任意のフィールド):

Android:background="@drawable/customshape"

誰かがそれが有用であると思うことを願っています...

367
Legend

それはうまくいきましたが、背景色もすべて削除しました。ボーダーだけを作成し、その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> 
56
Kevin Parker

@ kris-van-bael

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

listView.setSelector(R.color.transparent);

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

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

更新

最近の解決策は、CardViewを使用して、丸い角をサポートすることです。


元の回答*

私が見つけた別の方法は、レイアウトの上部に画像を描画して、レイアウトをマスクすることでした。役立つかもしれません。チェックアウト Android XMLの角が丸くなっているクリップ

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だけでなく、ドロアブルの一般的なソリューションを解決します。

3
dr_g

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

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

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

<?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>
2

境界線を作成するには、別のxmlファイルを作成し、ドローアブルフォルダー内のソリッドとコーナーのプロパティを作成し、バックグラウンドで呼び出す必要があります。

1
pawan kumar

これは私にとって非常に便利でした。独自の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
Machado

実際、最良の解決策はこのリンクで説明されていると思います:

http://blog.synyx.de/2011/11/Android-listview-with-rounded-corners/

要するに、上部、下部、下部のアイテムに異なる背景を使用するため、上部と下部のアイテムは丸みを帯びます。

1

他のビューの上にレイアウトし、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);
    }
}
0
mbonnin