0

ここにリストされている他の多くの投稿と同様に、放射状グラデーションに苦労しています。投稿123 ...

私は2つのことをしたい:

  1. オーラ効果を得るために、背景のドローアブルとしてセレクターを持つボタンの周りにグラデーションを設定します
  2. このグラデーション半径を調整して、画面の解像度/サイズとは無関係に同じ感覚を持たせます。

これまでに行ったこと: 解決策1

周りにあるいくつかのソリューションを実装しようとしました。私はここに私の2つのベストトライを示します。ボタンの周りを囲んでいるレイアウトの背景に、グラデーション付きのドローアブルを設定しました。それはポイントを満たします 1)

<FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/custom_background"
        android:gravity="center"
        android:padding="@dimen/padding_extra_large" >

        <Button
            android:id="@+id/snap_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/custom_button" />
</FrameLayout>

これは私の@drawable/custom_background

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item>

    <!-- Circular gradient -->
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle" >
        <gradient
            android:endColor="#ffdbdbdb"
            android:gradientRadius="180"
            android:startColor="#ff000000"
            android:type="radial" 
            android:innerRadiusRatio="2"
            />
    </shape>
</item>

これまでに行ったこと: 解決策2

効果は良好ですがandroid:gradientRadius="180"、画面ごとに調整する必要があります。投稿 1 はいくつかの解決策を提供し、レイアウトとビューをカスタマイズしようとしましたが、クラッシュしました。一部の構成は失敗しませんでした (バックグラウンドをルート レイアウトに設定しましたが、この場合は onDraw が呼び出されませんでした)。

カスタマイズされたビュー:

public class GradientView extends View {

Paint paint;
RadialGradient gradient;
int maxSize;

public GradientView(Context context) {
    super(context);
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    this.setWillNotDraw(false);
    // TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas) {
    Dbg.e("RelativeLayoutSnapBook", " -  onDraw !!!");
    maxSize = Math.max(getHeight(), getWidth());
    RadialGradient gradient = new RadialGradient(
            getWidth()/2,
            getHeight()/2,
            maxSize, 
            new int[] {Color.RED, Color.BLACK},
            new float[] {0, 1}, 
            android.graphics.Shader.TileMode.CLAMP);

    paint.setDither(true);
    paint.setShader(gradient);

    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
}

そして、このビューはここに行きます:

        <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="@dimen/padding_extra_large" >

        <com.snapcar.rider.widget.GradientView
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <Button
            android:id="@+id/snap_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/snap_button" />
    </FrameLayout>

これらはfail : エラーで、スタックとスタックのインターンエラーでフラグメントを膨らませます:

10-29 18:55:25.794: E/AndroidRuntime(11828): FATAL EXCEPTION: main
10-29 18:55:25.794: E/AndroidRuntime(11828): android.view.InflateException: Binary XML file line #33: Error inflating class com.xxx.widget.GradientView
10-29 18:55:25.794: E/AndroidRuntime(11828): Caused by: java.lang.ClassNotFoundException: com.xxx.rider.widget.GradientView in loader dalvik.system.PathClassLoader[/system/framework/com.google.android.maps.jar:/data/app/com.snapcar.rider-1.apk]

それをするのを手伝ってくれませんか?どうもありがとう!

編集:誰か?

4

1 に答える 1

0

解決しました!とても面倒です :/ Photoshop を知っているなら、それを使ったほうがいいと思います!

この投稿のおかげで、次のように進むことができました: multiple-gradrient最初のコード抽出のみが使用されましたが、この投稿にたどり着いた場合、投稿全体に興味があるかもしれません。

したがって、グローバル レイアウトでコールバックを使用して、コードでグラデーションを完全に定義します。

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.v(TAG, "- onCreateView Fragment");
    root = inflater.inflate(R.layout.fragment_layout, null);
    root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Log.e(TAG, "- On Layout Completed ! ");
            final FrameLayout frame = (FrameLayout) root.findViewById(R.id.frame_layout_gradient);
            ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
                @Override
                public Shader resize(int width, int height) {
                    Log.e(TAG, " - onGlobalLayout : getWidth = "+ frame.getWidth() +" - getHeight = "+ frame.getHeight() );
                    RadialGradient lg = new RadialGradient(frame.getWidth()/2, frame.getHeight()/2, 
                            frame.getWidth()/2, Color.BLACK, Color.parseColor("#FFdbdbdb"),  TileMode.CLAMP);
                    return lg;
                }
            };
            PaintDrawable p = new PaintDrawable();
            p.setShape(new OvalShape());
            p.setShaderFactory(sf);
            frame.setBackgroundDrawable((Drawable)p);
        }
    }
            );

Color.parseColor("#FFdbdbdb")RadialGradient のリタード コンストラクターが参照を正しく読み取ることができないため、このトリック が必要です。R.color.the_gray_I_want

私のframeLayoutは正方形なので、私の場合、OvalShapeは円を描きます。

このソリューションを使用すると、スクリーンの特性に完全に依存しないシャドーイングが実現します。

![結果 - SG3 から HTC ワイルドファイアまで変わらない! 1

于 2013-10-31T11:28:23.653 に答える