转载出处:王亟亟的大牛之路
平时我们一些指导类的内容都用一些ViewPager啊或者是在页面上盖一层半透明的布局来解释内容,
今天上一个库更好的针对性的对这部分实现进行优化,更好的用户体验。
项目结构:
运行效果:
MaterialShowcaseView的一些重要的方法,伸手党也要了解下:
MaterialShowcaseView 继承于FrameLayout,所以他也有FrameLayout比较重要的属性:
所有放在布局里的控件,都按照层次堆叠在屏幕的左上角。后加进来的控件覆盖前面的控件。
也就是为什么我们能一层一层盖了。
在自定义类的源码中画圆的onDraw方法中(代码的151行)
if (mEraser == null) {
mEraser = new Paint();
mEraser.setColor(0xFFFFFFFF);
mEraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mEraser.setFlags(Paint.ANTI_ALIAS_FLAG);
}
mCanvas.drawCircle(mXPosition, mYPosition, mRadius, mEraser);
//初始化了我们中间那个显示出来圆的一些属性,颜色,大小等
277行:设置我们要解释的文字
private void setContentText(CharSequence contentText) {
if (mContentTextView != null) {
mContentTextView.setText(contentText);
}
}
283行:设置点击消失的文字
private void setDismissText(CharSequence dismissText) {
if (mDismissButton != null) {
mDismissButton.setText(dismissText);
}
}
289-299:设置2种字体的颜色
private void setContentTextColor(int textColour) {
if (mContentTextView != null) {
mContentTextView.setTextColor(textColour);
}
}
private void setDismissTextColor(int textColour) {
if (mDismissButton != null) {
mDismissButton.setTextColor(textColour);
}
}
322:设置延迟时间
private void setDelay(long delayInMillis) {
mDelayInMillis = delayInMillis;
}
473:初始化一个ID(唯一)
public Builder singleUse(String showcaseID) {
showcaseView.singleUse(showcaseID);
return this;
}
618:初始化某个ID的试图
public static void resetSingleUse(Context context, String showcaseID) {
PrefsManager.resetShowcase(context, showcaseID);
}
627:初始化所有试图,不然所有效果只出现一次
public static void resetAll(Context context) {
PrefsManager.resetAll(context);
}
例子是一个简单的Demo:
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.btn_simple_example);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_custom_example);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_sequence_example);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_reset_all);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = null;
switch (v.getId()) {
case R.id.btn_simple_example:
intent = new Intent(this, SimpleSingleExample.class);
break;
case R.id.btn_custom_example:
intent = new Intent(this, CustomExample.class);
break;
case R.id.btn_sequence_example:
intent = new Intent(this, SequenceExample.class);
break;
case R.id.btn_reset_all:
MaterialShowcaseView.resetAll(this);
Toast.makeText(this, "All Showcases reset", Toast.LENGTH_SHORT).show();
break;
}
if(intent!=null){
startActivity(intent);
}
}
}
分析:
主Activity只是一个入口,通向三个事例的入口
CustomExample
public class CustomExample extends ActionBarActivity implements View.OnClickListener {
private Button mButtonShow;
private Button mButtonReset;
private static final String SHOWCASE_ID = "custom example";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_example);
mButtonShow = (Button) findViewById(R.id.btn_show);
mButtonShow.setOnClickListener(this);
mButtonReset = (Button) findViewById(R.id.btn_reset);
mButtonReset.setOnClickListener(this);
presentShowcaseView(1000); // one second delay
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_show) {
presentShowcaseView(0);
} else if (v.getId() == R.id.btn_reset) {
MaterialShowcaseView.resetSingleUse(this, SHOWCASE_ID);
Toast.makeText(this, "Showcase reset", Toast.LENGTH_SHORT).show();
}
}
private void presentShowcaseView(int withDelay) {
new MaterialShowcaseView.Builder(this)
.setTarget(mButtonShow)
.setDismissText("点击消失")
.setContentText("这是一段解释的内容")
.setContentTextColor(getResources().getColor(R.color.purple))
.setMaskColour(getResources().getColor(R.color.green))
.setDelay(withDelay) // withDelay秒后显示
.singleUse(SHOWCASE_ID) //提供了一个独特的ID,用于确保只有显示一次
.show();
}
}
CustomExample 对应的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="uk.co.deanwild.materialshowcaseviewsample.CustomExample">
<Button
android:id="@+id/btn_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="显示教程" />
<Button
android:layout_alignParentBottom="true"
android:id="@+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="重置" />
</RelativeLayout>
上图例子的SequenceExample
public class SequenceExample extends ActionBarActivity implements View.OnClickListener {
private Button mButtonOne;
private Button mButtonTwo;
private Button mButtonThree;
private Button mButtonReset;
private static final String SHOWCASE_ID = "sequence example";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sequence_example);
mButtonOne = (Button) findViewById(R.id.btn_one);
mButtonOne.setOnClickListener(this);
mButtonTwo = (Button) findViewById(R.id.btn_two);
mButtonTwo.setOnClickListener(this);
mButtonThree = (Button) findViewById(R.id.btn_three);
mButtonThree.setOnClickListener(this);
mButtonReset = (Button) findViewById(R.id.btn_reset);
mButtonReset.setOnClickListener(this);
presentShowcaseSequence(); // one second delay
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_show) {
presentShowcaseSequence();
} else if (v.getId() == R.id.btn_reset) {
MaterialShowcaseView.resetSingleUse(this, SHOWCASE_ID);
Toast.makeText(this, "Showcase reset", Toast.LENGTH_SHORT).show();
}
}
private void presentShowcaseSequence() {
ShowcaseConfig config = new ShowcaseConfig();
config.setDelay(500); //两个动画之间相隔半秒钟
MaterialShowcaseSequence sequence = new MaterialShowcaseSequence(this, SHOWCASE_ID);
sequence.setConfig(config);
sequence.addSequenceItem(mButtonOne,
"This is button one", "点击消失");
sequence.addSequenceItem(mButtonTwo,
"This is button two", "点击消失");
sequence.addSequenceItem(mButtonThree,
"This is button three", "点击消失");
sequence.start();
}
}
SequenceExample的布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="uk.co.deanwild.materialshowcaseviewsample.SequenceExample">
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Button 1" />
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="80dp"
android:text="Button 2" />
<Button
android:id="@+id/btn_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="50dp"
android:text="Button 3" />
<Button
android:id="@+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginRight="50dp"
android:text="Reset" />
</RelativeLayout>
这一系列的代码我就补贴全了,可以在源码中看
源码地址:http://yunpan.cn/cdpTYfPjG3GsM 访问密码 3003