Skip to content

Commit

Permalink
修复设置了FillPadding内外箭头位置不一致的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
cpiz committed Oct 31, 2016
1 parent 4f72ea6 commit ea1383e
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 69 deletions.
127 changes: 66 additions & 61 deletions library/src/main/java/com/cpiz/android/bubbleview/BubbleDrawable.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,27 +82,27 @@ void setFillPadding(float fillPadding) {
mFillPadding = fillPadding;
}

void rebuildShapes() {
buildBorderShape();
buildFillShape();
void updateShapes() {
updateBorderShape();
updateFillShape();
}

private void buildBorderShape() {
// 预留四周1/2的边框厚度,使得边框能够完全显示
private void updateBorderShape() {
mBorderShape.set(mOriginalShape);
mBorderShape.Rect.set(
mBorderShape.Rect.set( // 内缩四周1/2的边线厚度,使得边线能够完全显示
mOriginalShape.Rect.left + mOriginalShape.BorderWidth / 2 + (mArrowDirection.isLeft() ? mOriginalShape.ArrowHeight : 0),
mOriginalShape.Rect.top + mOriginalShape.BorderWidth / 2 + (mArrowDirection.isUp() ? mOriginalShape.ArrowHeight : 0),
mOriginalShape.Rect.right - mOriginalShape.BorderWidth / 2 - (mArrowDirection.isRight() ? mOriginalShape.ArrowHeight : 0),
mOriginalShape.Rect.bottom - mOriginalShape.BorderWidth / 2 - (mArrowDirection.isDown() ? mOriginalShape.ArrowHeight : 0)
);
buildArrowPeak(mArrowDirection, mBorderShape);

mBorderPath.reset();
buildPath(mBorderShape, mBorderPath);
// 外层的箭头顶点位置通过箭头位置策略、箭头偏移设定、目标位置决定
updateBorderArrowPeak(mArrowDirection, mArrowPosPolicy, mArrowTo, mBorderShape);

updatePath(mBorderShape, mBorderPath);
}

private void buildFillShape() {
private void updateFillShape() {
mFillShape.set(mBorderShape);
mFillShape.BorderWidth = 0;
mFillShape.Rect.set(
Expand All @@ -121,25 +121,61 @@ private void buildFillShape() {

mFillShape.ArrowHeight = (float) (h + mOriginalShape.BorderWidth / 2 + mFillPadding);
mFillShape.ArrowWidth = mFillShape.ArrowHeight * mOriginalShape.ArrowWidth / mOriginalShape.ArrowHeight;
buildArrowPeak(mArrowDirection, mFillShape);

mFillPath.reset();
buildPath(mFillShape, mFillPath);
// 内层的箭头顶点位置通过外层边线上的顶点位置来计算
updateFillArrowPeak(mArrowDirection, mBorderShape, mFillShape);

updatePath(mFillShape, mFillPath);
}

private static void updateFillArrowPeak(BubbleStyle.ArrowDirection direction, Shape borderShape, Shape outFillShape) {
switch (direction) {
case Left:
outFillShape.ArrowPeakX = outFillShape.Rect.left - outFillShape.ArrowHeight;
outFillShape.ArrowPeakY = borderShape.ArrowPeakY;
break;
case Right:
outFillShape.ArrowPeakX = outFillShape.Rect.right + outFillShape.ArrowHeight;
outFillShape.ArrowPeakY = borderShape.ArrowPeakY;
break;
case Up:
outFillShape.ArrowPeakX = borderShape.ArrowPeakX;
outFillShape.ArrowPeakY = outFillShape.Rect.top - outFillShape.ArrowHeight;
break;
case Down:
outFillShape.ArrowPeakX = borderShape.ArrowPeakX;
outFillShape.ArrowPeakY = outFillShape.Rect.bottom + outFillShape.ArrowHeight;
break;
default:
break;
}
}

private void buildArrowPeak(BubbleStyle.ArrowDirection direction, Shape shape) {
private void updateBorderArrowPeak(BubbleStyle.ArrowDirection direction, BubbleStyle.ArrowPosPolicy policy, PointF arrowTo, Shape outShape) {
switch (direction) {
case Left:
buildLeftArrowPeak(shape);
outShape.ArrowPeakX = outShape.Rect.left - outShape.ArrowHeight;
outShape.ArrowPeakY = bound(outShape.Rect.top + outShape.TopLeftRadius + outShape.ArrowWidth / 2 + outShape.BorderWidth / 2,
getLeftRightArrowPeakY(policy, arrowTo, outShape), // 确保弧角的显示
outShape.Rect.bottom - outShape.BottomLeftRadius - outShape.ArrowWidth / 2 - outShape.BorderWidth / 2);
break;
case Up:
buildUpArrowPeak(shape);
outShape.ArrowPeakX = bound(outShape.Rect.left + outShape.TopLeftRadius + outShape.ArrowWidth / 2 + outShape.BorderWidth / 2,
getUpDownArrowPeakX(policy, arrowTo, outShape),
outShape.Rect.right - outShape.TopRightRadius - outShape.ArrowWidth / 2 - outShape.BorderWidth / 2);
outShape.ArrowPeakY = outShape.Rect.top - outShape.ArrowHeight;
break;
case Right:
buildRightArrowPeak(shape);
outShape.ArrowPeakX = outShape.Rect.right + outShape.ArrowHeight;
outShape.ArrowPeakY = bound(outShape.Rect.top + outShape.TopRightRadius + outShape.ArrowWidth / 2 + outShape.BorderWidth / 2,
getLeftRightArrowPeakY(policy, arrowTo, outShape),
outShape.Rect.bottom - outShape.BottomRightRadius - outShape.ArrowWidth / 2 - outShape.BorderWidth / 2);
break;
case Down:
buildDownArrowPeak(shape);
outShape.ArrowPeakX = bound(outShape.Rect.left + outShape.BottomLeftRadius + outShape.ArrowWidth / 2 + outShape.BorderWidth / 2,
getUpDownArrowPeakX(policy, arrowTo, outShape),
outShape.Rect.right - outShape.BottomRightRadius - outShape.ArrowWidth / 2 - outShape.BorderWidth / 2);
outShape.ArrowPeakY = outShape.Rect.bottom + outShape.ArrowHeight;
break;
}
}
Expand Down Expand Up @@ -211,7 +247,8 @@ public int getOpacity() {
return PixelFormat.UNKNOWN;
}

private void buildPath(Shape shape, Path path) {
private void updatePath(Shape shape, Path path) {
path.reset();
switch (mArrowDirection) {
case None:
buildWithNoneArrow(shape, path);
Expand Down Expand Up @@ -309,77 +346,45 @@ private void buildWithDownArrow(Shape shape, Path path) {
path.lineTo(shape.ArrowPeakX, shape.ArrowPeakY);
}

private void buildLeftArrowPeak(Shape shape) {
shape.ArrowPeakX = shape.Rect.left - shape.ArrowHeight;
shape.ArrowPeakY = bound(shape.Rect.top + shape.TopLeftRadius + shape.ArrowWidth / 2 + shape.BorderWidth / 2,
getLeftRightArrowPeakY(shape), // 确保弧角的显示
shape.Rect.bottom - shape.BottomLeftRadius - shape.ArrowWidth / 2 - shape.BorderWidth / 2);
shape.ArrowDelta = shape.ArrowPeakY;
}

private void buildRightArrowPeak(Shape shape) {
shape.ArrowPeakX = shape.Rect.right + shape.ArrowHeight;
shape.ArrowPeakY = bound(shape.Rect.top + shape.TopRightRadius + shape.ArrowWidth / 2 + shape.BorderWidth / 2,
getLeftRightArrowPeakY(shape),
shape.Rect.bottom - shape.BottomRightRadius - shape.ArrowWidth / 2 - shape.BorderWidth / 2);
shape.ArrowDelta = shape.ArrowPeakY;
}

private void buildUpArrowPeak(Shape shape) {
shape.ArrowPeakX = bound(shape.Rect.left + shape.TopLeftRadius + shape.ArrowWidth / 2 + shape.BorderWidth / 2,
getUpDownArrowPeakX(shape),
shape.Rect.right - shape.TopRightRadius - shape.ArrowWidth / 2 - shape.BorderWidth / 2);
shape.ArrowPeakY = shape.Rect.top - shape.ArrowHeight;
shape.ArrowDelta = shape.ArrowPeakX;
}

private void buildDownArrowPeak(Shape shape) {
shape.ArrowPeakX = bound(shape.Rect.left + shape.BottomLeftRadius + shape.ArrowWidth / 2 + shape.BorderWidth / 2,
getUpDownArrowPeakX(shape),
shape.Rect.right - shape.BottomRightRadius - shape.ArrowWidth / 2 - shape.BorderWidth / 2);
shape.ArrowPeakY = shape.Rect.bottom + shape.ArrowHeight;
shape.ArrowDelta = shape.ArrowPeakX;
}

private float getLeftRightArrowPeakY(Shape shape) {
private static float getLeftRightArrowPeakY(BubbleStyle.ArrowPosPolicy policy, PointF arrowTo, Shape shape) {
float y;
switch (mArrowPosPolicy) {
switch (policy) {
case TargetCenter:
y = shape.Rect.centerY() + mArrowTo.y;
y = shape.Rect.centerY() + arrowTo.y;
break;
case SelfCenter:
y = shape.Rect.centerY();
break;
case SelfBegin:
y = shape.Rect.top;
y += mOriginalShape.ArrowDelta;
y += shape.ArrowDelta;
break;
case SelfEnd:
y = shape.Rect.bottom;
y -= mOriginalShape.ArrowDelta;
y -= shape.ArrowDelta;
break;
default:
y = 0;
}
return y;
}

private float getUpDownArrowPeakX(Shape shape) {
private static float getUpDownArrowPeakX(BubbleStyle.ArrowPosPolicy policy, PointF arrowTo, Shape shape) {
float x;
switch (mArrowPosPolicy) {
switch (policy) {
case TargetCenter:
x = shape.Rect.centerX() + mArrowTo.x;
x = shape.Rect.centerX() + arrowTo.x;
break;
case SelfCenter:
x = shape.Rect.centerX();
break;
case SelfBegin:
x = shape.Rect.left;
x += mOriginalShape.ArrowDelta;
x += shape.ArrowDelta;
break;
case SelfEnd:
x = shape.Rect.right;
x -= mOriginalShape.ArrowDelta;
x -= shape.ArrowDelta;
break;
default:
x = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ void updateDrawable(int width, int height, boolean drawImmediately) {
mBubbleDrawable.setArrowPosDelta(mArrowPosDelta);
mBubbleDrawable.setArrowHeight(mArrowHeight);
mBubbleDrawable.setArrowWidth(mArrowWidth);
mBubbleDrawable.rebuildShapes();
mBubbleDrawable.updateShapes();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mParentView.setBackground(mBubbleDrawable);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ public void showArrowTo(View anchor, RelativePos relativePos, int marginH, int m
PopupProp outProp = new PopupProp();
getPopupProp(screenWidth, screenHeight, navigationBarHeight, anchorRect, contentWidth, contentHeight, relativePos, marginH, marginV, mPadding, outProp);

// mBubbleView.setArrowDirection(outProp.direction); // 自动调整方向了
setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
setAnimationStyle(outProp.animationStyle);
Expand Down
8 changes: 5 additions & 3 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
package="com.cpiz.android.bubbleviewsample"
xmlns:android="http://schemas.android.com/apk/res/android">
<manifest package="com.cpiz.android.bubbleviewsample"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:allowBackup="true"
Expand All @@ -21,6 +21,8 @@
android:name=".PopupWindowSampleActivity"
android:label="PopupWindow Sample"
android:windowSoftInputMode="stateHidden"/>
<activity android:name=".BubbleTextViewSampleActivity">
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.cpiz.android.bubbleviewsample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.cpiz.android.bubbleview.BubbleTextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class BubbleTextViewSampleActivity extends AppCompatActivity {

@BindView(R.id.bubble_text_sample)
BubbleTextView mBubbleTextSample;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bubble_text_view_sample);
ButterKnife.bind(this);
}

@OnClick({R.id.view_anchor})
public void onClick(View view) {
mBubbleTextSample.updateDrawable();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ protected void onCreate(Bundle savedInstanceState) {
}

@SuppressWarnings("unused")
@OnClick({R.id.btn_bubble_popup_window_sample})
@OnClick({R.id.btn_bubble_popup_window_sample, R.id.btn_bubble_text_view_sample})
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_bubble_popup_window_sample:
startActivity(new Intent(MainActivity.this, PopupWindowSampleActivity.class));
break;
case R.id.btn_bubble_text_view_sample:
startActivity(new Intent(MainActivity.this, BubbleTextViewSampleActivity.class));
break;
}
}
}
57 changes: 57 additions & 0 deletions sample/src/main/res/layout/activity_bubble_text_view_sample.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/activity_bubble_text_view_sample"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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="com.cpiz.android.bubbleviewsample.BubbleTextViewSampleActivity"
tools:ignore="HardcodedText,RtlHardcoded">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="240dp">

<TextView
android:id="@+id/view_anchor"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:layout_marginBottom="20dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="Click Me"
android:textColor="@android:color/white"/>

<!--app:bb_arrowDirection="Left"-->
<com.cpiz.android.bubbleview.BubbleTextView
android:id="@+id/bubble_text_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_toRightOf="@id/view_anchor"
android:padding="30dp"
android:text="Arrow"
android:textColor="@android:color/white"
app:bb_arrowHeight="20dp"
app:bb_arrowTo="@id/view_anchor"
app:bb_arrowWidth="30dp"
app:bb_borderColor="@color/colorPrimary"
app:bb_borderWidth="6dp"
app:bb_fillPadding="10dp"
app:bb_cornerBottomLeftRadius="20dp"
app:bb_cornerBottomRightRadius="10dp"
app:bb_cornerRadius="4dp"
app:bb_cornerTopLeftRadius="0dp"
app:bb_cornerTopRightRadius="4dp"
app:bb_fillColor="@android:color/holo_red_light"/>
</RelativeLayout>

</LinearLayout>
10 changes: 9 additions & 1 deletion sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,18 @@
android:textSize="24sp"
android:textStyle="bold"/>

<Button
android:id="@+id/btn_bubble_text_view_sample"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:text="BubbleTextView Sample"/>

<Button
android:id="@+id/btn_bubble_popup_window_sample"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bubble_popup_window_sample"/>
android:layout_marginBottom="2dp"
android:text="BubblePopupWindow Sample"/>
</LinearLayout>
</ScrollView>
1 change: 0 additions & 1 deletion sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
<string name="app_name">BubbleView</string>
<!--<string name="sample_text">A control/container with an arrow for Android, which can be fully customized by code or XML layout file.</string>-->
<string name="sample_text">A control/container</string>
<string name="bubble_popup_window_sample">BubblePopupWindow Sample</string>
</resources>

0 comments on commit ea1383e

Please sign in to comment.