3

アプリケーション「Google Play」では、任意のアイテム (LinearLayout、ボタン、imageview、textview ...) をクリックすると、青いコートが表示されることがわかります。

上にいるのは、android: state_pressed = "true" android: state_focused = "true" ... の単純な背景ではありません ...

その効果を適用する方法はありますか?

たとえば、複数の画像とテキストを含む LinearLayout があります。この LinearLayout は「ボタン」として機能します。私の意図は、Google のように、上部に青いレイヤーを持つ外観の変更を押すことです。

私は通常、カスタム背景を使用しますが、それは適用されますが、適用されません。

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:state_focused="true" android:drawable="@drawable/focus_blue_default" />
</selector>

そしてfocus_blue_default.xml :

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#8051C9EC" />
</shape>
</item>
</layer-list>

ここに画像の説明を入力

4

4 に答える 4

3

これは参考用であり、実用的ではないと思いますし、テストもされていません...

答えが受け入れられたので、このコードの問題点を述べます (今考えられるもの):

  1. @ user2558882 が回答に関するコメントで述べたように、サブクラスが使用setContentView(view, params)するとパラメーターが失われます。
  2. これは、膨張したビュー、つまりアダプターでは機能しません。それでも、fix(View)インフレートされたビューを呼び出すことで解決できます。
  3. 色のみで動作します。これも修正できます。
  4. これは sherlock-actionbar で動作する可能性があると思います。
  5. コードはテストされていないため、テストしてください。
  6. RelativeLayout を追加することで、ビュー ツリー全体をもう 1 レベルシフトします。これは、 を使用して修正できますaddContentView。私はこの RelativeLayout を使用しました。なぜなら、私はこれにすばやく答えたからです。また、現在のコードはすべての電話と API でより適切に機能すると思います。これは、ソリューション全体が RelativeLayout で圧縮され、その動作がかなり一貫しているためです。結局、私はRelativeLayout.LayoutParamsこの ViewGroup の非常に基本的な機能だけを使用しています。

解決

BaseActivity.javaを作成します。

package mobi.sherif.overlay;

import android.app.Activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;

public class BaseActivity extends Activity {
    RelativeLayout mRl;
    View mImage;
    View mContent;
    @Override
    public void setContentView(int layoutResID) {
        setContentView(LayoutInflater.from(this).inflate(layoutResID, null));
    }
    @Override
    public void setContentView(View view) {
        setContentView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    }
    @Override
    public void setContentView(View view, LayoutParams params) {
        mContent = view;
        fix(view);
        push(view);
    }
    protected void refix() {
        fix(mContent);
    }
    private void push(View view) {
        mRl = new RelativeLayout(this);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        mRl.addView(view, params);
        mImage = new View(this);
        mImage.setVisibility(View.GONE);
        params = new RelativeLayout.LayoutParams(0, 0);
        mRl.addView(mImage, params);
        super.setContentView(mRl);
    }
    protected void fix(View child) {
        if (child == null)
            return;

        doFix(child);
        if (child instanceof ViewGroup) {
            fix((ViewGroup) child);
        }
    }

    private void fix(ViewGroup parent) {
        for (int i = 0; i < parent.getChildCount(); i++) {
            fix(parent.getChildAt(i));
        }
    }
    private void doFix(View child) {
        if(child.getTag()!=null && child.getTag().getClass() == String.class) {
            String color = (String) child.getTag();
            int theColor;
            try {
                theColor = Color.parseColor(color);
                child.setTag(theColor);
            } catch (Exception e) {
                theColor = -1;
            }
            if(theColor != -1) {
                child.setOnTouchListener(new OnTouchListener() {

                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            mImage.setBackgroundColor((Integer) v.getTag());
                            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mImage.getLayoutParams();
                            params.leftMargin = getLeftWithRespectTo(v, mRl);
                            params.topMargin = getTopWithRespectTo(v, mRl);
                            params.width = v.getWidth();
                            params.height = v.getHeight();
                            mImage.setVisibility(View.VISIBLE);
                            mImage.requestLayout();
                            break;
                        case MotionEvent.ACTION_CANCEL:
                        case MotionEvent.ACTION_UP:
                            mImage.setVisibility(View.GONE);
                        default:
                            break;
                        }
                        return v.onTouchEvent(event);
                    }
                });
            }
        }
    }
    private int getLeftWithRespectTo(View view, View relative) {
        int left = 0;
        View temp = view;
        do {
            left += temp.getLeft();
            temp = (View) temp.getParent();
        }
        while(temp!=relative);
        return left;
    }
    private int getTopWithRespectTo(View view, View relative) {
        int top = 0;
        View temp = view;
        do {
            top += temp.getTop();
            temp = (View) temp.getParent();
        }
        while(temp!=relative);
        return top;
    }
}

次に、この BaseActivity と、それにオーバーレイするビューを拡張して、次のandroid:tag="#AARRGGBB"ように色を使用します。

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:tag="#331111ff"
    android:text="@string/hello_world" />

テスト:次のようにactivity_main.xmlで xml を使用する場合:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="17dp"
        android:layout_marginTop="90dp"
        android:tag="#331111ff"
        android:text="TextView" />

</RelativeLayout>

これをMainActivity.javaとして使用します。

package mobi.sherif.overlay;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class MainActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);
        findViewById(R.id.textView1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "text tpicjed", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
于 2013-09-26T14:23:30.310 に答える
1

私が知る限り、Google Play で使用されている (個々のアイテムの) コンテナー レイアウトは RelativeLayout です。RelativeLayout を使用すると、この効果を実現するのは非常に簡単です。ほとんどのコンポーネントはすでに準備ができています。最後のステップは次のとおりです。

レイアウト:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white" >

    <ImageView 
    ........../>

    <TextView 
    ........../>

    <WhateverView 
    ........../>

    <!--     The final piece -->

    <View
        android:id="@+id/clickableView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:background="@drawable/state_selector_drawable" />

</RelativeLayout>

そして、アクティビティで、このビューに OnClickListener を追加します。

View clickableView = findViewById(R.id.clickableView);

clickableView.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {

        Toast.makeText(MainActivity.this,
                 "Click registered.", Toast.LENGTH_SHORT).show();

    }

});

すでに LinearLayout が設定されていて、RelativeLayout に切り替えたくない場合を考えてみましょう。それはいいです。LinearLayout をその子とともに RelativeLayout 内に配置します。上記で定義したビューを追加します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white" >


        <ImageView 
        ........../>

        <TextView 
        ........../>

        <WhateverView 
        ........../>

    </LinearLayout>

    <!--     The final piece -->

    <View
        android:id="@+id/clickableView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:background="@drawable/state_selector_drawable" />

</RelativeLayout>
于 2013-09-25T20:25:53.637 に答える
1

これはまさにあなたが求めているものではないかもしれませんが、コントロールを押したときにコントロールを半透明にし、押すのをやめると通常の表示に戻る、簡単に再利用できる方法を思いつきました.

コードは次のとおりです。

public class ViewTouchHighlighter implements OnTouchListener 
{

    @Override
    public boolean onTouch(View v, MotionEvent event) 
    {
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
            AlphaAnimation animation = new AlphaAnimation(1, 0.5f);
            animation.setDuration(0);
            v.startAnimation(animation);

        }
        else
        {
            AlphaAnimation animation = new AlphaAnimation(0.5f, 1);
            animation.setDuration(0);
            v.startAnimation(animation);
        }
        return false;
    }

}

次に、任意のビューを簡単に取得して、次のように動作させることができます。

view.setOnTouchListener(new ViewTouchHighlighter());

これはあなたが探しているものとは少し違うと思いますが、強調表示だけが必要な場合は、これが良い解決策になる可能性があります.

青色の効果を主張している場合、および/または単に触れたときではなく、選択したときに青色に見えるものが必要な場合は、@Danielに同意し、任意のコンポーネントから継承することを提案します.でこれを行い、そこにカスタム コードを追加することをお勧めします。

于 2013-09-25T14:55:57.210 に答える