在应用程序“Google Play”中,我们可以看到,如果您点击任何项目(LinearLayout,button,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>
答案 0 :(得分:3)
这仅供参考,我不认为它是实用的,也没有经过测试......
由于接受了答案,我将陈述此代码的问题(我现在能想到的):
setContentView(view, params)
,则参数将丢失。fix(View)
来解决。addContentView
修复。我确实使用了这个RelativeLayout,因为我快速回答了这个问题,并且我认为当前的代码在所有手机和apis上都能更好地运行。这是正确的,因为整个解决方案在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" />
TEST: 如果您在 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();
}
});
}
}
答案 1 :(得分:1)
假设您希望在Button
上实现此效果:
Button
类true
(我会说你可以根据onTouchEvent(MotionEvent event)
中检测到的触摸事件来设置它的值 - 只需在课堂上覆盖它并分析这些事件。)onDraw()
方法,在调用super之后,添加一个if子句,如果布尔标志为真,则会在整个视图上绘制这个彩色矩形(使用Paint
)。几点重要:
drawable
来实现相同的效果。 boolean
值后,您可能需要使视图无效。答案 2 :(得分: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&amp;建议您从可能要执行此操作的任何组件继承并在那里添加自定义代码。
答案 3 :(得分: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>