我正在编写一个SDK来编写教程。在这个SDK中,我展示了一个聚光灯片段,在其中我基本上创建了一个背景画布,在那里我画了一个更暗的背景和一个透明的矩形,它聚焦于所需的视图。
在某些情况下,此视图可能会移动。例如,使用my的开发人员会在聚焦视图之前创建视图的时间折叠,从而使聚焦视图移动,因此,我的聚光灯停留在错误的位置。
的问题是:如何识别屏幕上的视图运动,以便相应地更新我的聚光灯片段?
发布于 2017-09-14 09:03:45
使用OnPreDrawListener找到了一个更好的解决方案
private final ViewTreeObserver.OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (!mAttached) {
removePreDrawObserver(null);
return true;
}
handleViewDraw();
return true;
}
};每次重绘视图时都会调用onPreDraw方法。
其中的handleViewDraw方法如下所示:
private void handleViewDraw() {
if (if mViewAnchor != null) {
View view = mViewAnchor.get();
if (null != view && view.getVisibility() == VISIBLE) {
view.getLocationOnScreen(mTempLocation);
if (mOldLocation == null) {
mOldLocation = new int[]{mTempLocation[0], mTempLocation[1]};
}
if (isTargetViewLocationChanged()) {
handleVisibleTargetViewLocationChange();
}
mOldLocation[0] = mTempLocation[0];
mOldLocation[1] = mTempLocation[1];
} else {
mView.setVisibility(INVISIBLE);
}
} else {
mView.setVisibility(INVISIBLE);
}
}
private boolean isTargetViewLocationChanged() {
Log.d(TAG, "Old: " + mOldLocation[1] + " ,TEMP: " + mTempLocation[1]);
return mOldLocation[0] != mTempLocation[0] || mOldLocation[1] != mTempLocation[1];
}使用此方法,只有在视图移动时才会通知您,与另一个答案中提供的'active‘解决方案不同,这是一个’被动‘解决方案,只有在视图实际移动时才会运行handleVisibleTargetViewLocationChange方法。
发布于 2017-07-03 07:18:11
我现在想出的唯一解决方案是下面的'active‘解决方案,我每隔半秒钟运行一个Task,检查目标视图的LocationOnScreen。如果目标视图改变了坐标,我会更新片段。这个解决方案可以工作,但我仍然在寻找一个“被动”解决方案,它可以在位置更改时更新我,而不是每隔半秒钟测试一次:
@Override
public void onStart() {
super.onStart();
final View targetView = mDrawDataPojo.getWalkthroughMetaPojo().getTargetView().getView();
if (targetView != null) {
targetView.getLocationOnScreen(mOriginalLocationOnScreen);
mTimer = new Timer();
mTimer.schedule(new TargetViewChangeListener(), 0, 500);
}
...
}
@Override
public void onPause() {
super.onPause();
if (mTimer != null) {
mTimer.cancel();
}
...
}
class TargetViewChangeListener extends TimerTask {
public void run() {
int[] currentLocation = new int[2];
mDrawDataPojo.getWalkthroughMetaPojo().getTargetView().getView().getLocationOnScreen(currentLocation);
if (currentLocation[0] != mOriginalLocationOnScreen[0] || currentLocation[1] != mOriginalLocationOnScreen[1]) {
final boolean isActionBar = ABUtils.isActionBarActivity(getActivity());
final int containerId;
try {
mDrawDataPojo.getWalkthroughMetaPojo().setTargetView(new SpotlightTargetView(getActivity(), mDrawDataPojo.getWalkthroughMetaPojo().getTargetView().getView()));
containerId = AndroidUtils.getContainerId(getActivity(), isActionBar);
ABPromotionFragment abPromotionFragment = ABPromotionFragment.newInstance(mDrawDataPojo.getViewDataPojo(), null, mDrawDataPojo.getWalkthroughMetaPojo());
FragmentManager fragmentManager = getActivity().getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
fragmentTransaction.replace(containerId, abPromotionFragment);
fragmentTransaction.commitAllowingStateLoss();
} catch (Exception e) {
ABLogger.d("TargetViewChangeListener - TimerTask - exception: " + e);
}
}
}
}https://stackoverflow.com/questions/44828866
复制相似问题