在一个 Android 应用程序中,我有一个列表视图,其中背景仅在一个角上圆角。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
>
<stroke
android:width="0dip"
android:color="@color/content_screen_scroll_view_border"
/>
<padding
android:left="0dip"
android:top="@dimen/content_screen_scroll_view_border"
android:right="0dip"
android:bottom="@dimen/content_screen_scroll_view_border"
/>
<corners
android:bottomRightRadius="20dip"
/>
<gradient
android:angle="270"
android:startColor="@color/listview_selected_item_start"
android:endColor="@color/listview_selected_item_end"
android:type="linear"
/>
当我上下翻页然后选择底部条目时,所选条目超出圆角。我尝试了各种解决方案,但没有找到一种似乎只适用于一个圆角的解决方案。
所以,我使用了我找到的以下代码(不记得在哪里):
package org.pskink.roundlist;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class RoundListTest extends Activity {
private ListView mList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mList = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
adapter.add("One");
adapter.add("Two");
adapter.add("Three");
adapter.add("Four");
adapter.add("Five");
adapter.add("Six");
adapter.add("Seven");
adapter.add("Eight");
adapter.add("Nine");
adapter.add("Ten");
adapter.add("Eleven");
adapter.add("Twelve");
mList.setAdapter(adapter);
mList.setSelector(new Selector(mList));
mList.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
GradientDrawable gd = new GradientDrawable();
gd.setColor(0xffaaaaaa);
gd.setCornerRadii(new float[]{0,0,0,0,0,0,20,20});
mList.setBackgroundDrawable(gd);
}
class Selector extends Drawable {
private static final String TAG = "Selector";
private Paint mPaint;
private AdapterView mList;
private RectF mRectF;
public Selector(AdapterView list) {
mList = list;
mPaint = new Paint();
mPaint.setColor(0x80ff8000);
mRectF = new RectF();
}
@Override
public void draw(Canvas canvas) {
Rect b = getBounds();
int position = mList.getSelectedItemPosition();
canvas.save();
canvas.clipRect(b.left, b.top, b.right, (b.bottom + b.top) / 2);
drawHalf(canvas, b, position == 0);
canvas.restore();
canvas.save();
canvas.clipRect(b.left, (b.bottom + b.top) / 2, b.right, b.bottom);
drawHalf(canvas, b, position == mList.getAdapter().getCount() - 1 && b.bottom == mList.getHeight());
canvas.restore();
Log.d(TAG, "draw " + b);
}
private void drawHalf(Canvas canvas, Rect b ,boolean round) {
if (round) {
mRectF.set(b);
canvas.drawRoundRect(mRectF, 20, 20, mPaint);
} else {
canvas.drawRect(b, mPaint);
}
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
}
}
package org.pskink.roundlist;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.RectF;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ListView;
public class RoundedRectListView extends ListView {
private static final float RADIUS = 16;
private Path mClip;
public RoundedRectListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
GradientDrawable gd = new GradientDrawable();
gd.setCornerRadius(RADIUS);
gd.setColor(0xff208020);
setBackgroundDrawable(gd);
setCacheColorHint(0);
setVerticalFadingEdgeEnabled(false);
StateListDrawable sld = new StateListDrawable();
sld.addState(
PRESSED_ENABLED_STATE_SET,
new GradientDrawable(Orientation.LEFT_RIGHT, new int[] {0xffa58cf5, 0xffa13f99}));
sld.addState(
EMPTY_STATE_SET,
new GradientDrawable(Orientation.LEFT_RIGHT, new int[] {0xff058cf5, 0xff013f99}));
setSelector(sld);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.d("onSizeChanged", "sizes" + w + " , " + h + " , " + oldw + " , " + oldh + " , ");
mClip = new Path();
RectF rect = new RectF(0, 0, w, h);
mClip.addRoundRect(rect, RADIUS, RADIUS, Direction.CW);
}
@Override
protected void dispatchDraw(Canvas canvas) {
Log.d("dispatchDraw","");
canvas.save();
canvas.clipPath(mClip);
super.dispatchDraw(canvas);
canvas.restore();
}
}
并使用 RoundedRectListView 作为布局中列表视图的对象:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="8dip"
>
<org.pskink.roundlist.RoundedRectListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/list"
/>
</LinearLayout>
然后发生的事情是,除了左下角之外,它会绕过所有角落。我似乎无法弄清楚如何让它只圆左下角的那个。