我有一个带有4个按钮的片段。我想在一个哈希映射中保存每个按钮在屏幕上的位置(每个按钮将映射到它在屏幕上的位置)。这样做最简单的方法是什么? 在使用片段之前,我使用了onWindowFocusChanged方法(在Activity中),我可以在其中检索按钮位置。使用片段我尝试使用ViewTreeObserver(使用GlobalLayoutListener)。在匿名类中,我可以检索并保存(在实例变量中)按钮位置,但在其外部,这些值消失(等于0)。 怎么办呢?
谢谢!
编辑添加了一个代码段 -
public void getViewsPosition(final ArrayList<View> viewArr) {
for (final View v : viewArr) {
final ViewTreeObserver vto = v.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int[] i = new int[2];
v.getLocationOnScreen(i);
_rect = new Rect(i[0], i[1], i[0] + v.getWidth(), i[1]
+ v.getHeight());
view_to_rect.put(v, _rect);
if (Build.VERSION.SDK_INT < 16) {
vto.removeGlobalOnLayoutListener(this);
} else {
vto.removeOnGlobalLayoutListener(this);
}
}
});
}
Log.i(TAG, "size of view to rect = " + String.valueOf(view_to_rect.size()));
}
其中viewArr是此布局中所有视图的arrayList; view_to_rect是一个声明为:
的实例变量private static Map view_to_rect = new HashMap();
日志始终显示“rect = 0的视图大小”。
还附加了onViewCreated的实现:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i(TAG, "onViewCreated");
final ViewGroup _mainView = (ViewGroup) getView().findViewById(
R.id.fragment01);
getAllViews(viewsList, _mainView);
Log.i(TAG, "size of view list = " + String.valueOf(viewsList.size()));
getViewsPosition(viewsList);
}
从中调用getViewsPosition。
修改#2: 我会尽力澄清我的意图。我正在使用片段构建应用程序。比方说,每个片段有4个按钮。我希望这些按钮能够听取触摸事件,以便当用户触摸按钮并将手指移动到另一个按钮(不抬起他的手指)时,将会有按钮名称的音频反馈。为此,我需要拥有所有按钮位置,以便能够识别从一个按钮移动到另一个按钮(在onTouch方法中)。为此,我需要一个实例变量,它将所有按钮位置保持在屏幕上,我将能够在onTouch中使用它。您建议的解决方案无法解决问题,因为
之外public void getViewsPosition(final ArrayList viewArr)
view_to_rect的大小仍为0。
编辑#3:
以下是我尝试构建我的集合的过程:
1)类签名+集合和数组定义:
public class Fragment01 extends Fragment implements OnTouchListener,
OnClickListener{
private Map<View, Rect> view_to_rect = new HashMap<View, Rect>();
ArrayList<View> viewsList = new ArrayList<View>();
2)onViewCreated实现:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i(TAG, "onViewCreated");
final ViewGroup _mainView = (ViewGroup) getView().findViewById(
R.id.fragment01);
getAllViews(viewsList, _mainView);
Log.i(TAG, "size of view list = " + String.valueOf(viewsList.size()));
getViewsPosition(viewsList);
Log.i(TAG, "size of view to rect = " + String.valueOf(view_to_rect.size()));
}
3)getViewsPosition(...)和onPositioUpdate()方法 -
public void getViewsPosition(final ArrayList<View> viewArr) {
for (final View v : viewArr) {
final ViewTreeObserver vto = v.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int[] i = new int[2];
v.getLocationOnScreen(i);
_rect = new Rect(i[0], i[1], i[0] + v.getWidth(), i[1]
+ v.getHeight());
if (Build.VERSION.SDK_INT < 16) {
vto.removeGlobalOnLayoutListener(this);
} else {
vto.removeOnGlobalLayoutListener(this);
}
onPositionUpdate();
}
});
}
}
private void onPositionUpdate() {
}
第一次登录onViewCreated(...)是“视图列表大小= 7”。
我的问题是如何才能将第二个日志打印出来“将视图大小调整为rect = 7”?它总是返回0.
我可能不太了解如何在onPositionUpdate()方法中使用您的解决方案。如何实现以实现我的目标?
答案 0 :(得分:1)
仅在呈现视图时才会通知ViewTreeObserver, 你是什么意思
“但除此之外,这些价值已经消失了”
您可以在GlobalLayoutListener回调中获取按钮的位置,并将其保存为实例。请记住,您只能获得渲染的位置。
<强>提醒:强>
把这段代码
Log.i(TAG,“视图的大小= rect =”+ String.valueOf(view_to_rect.size()));
在public void onGlobalLayout(){}中,那么你将得到非零。
<强>为什么:强>
只调用onGlobalLayout方法,你可以得到非零值。
public void onGlobalLayout() {
int[] i = new int[2];
v.getLocationOnScreen(i);
_rect = new Rect(i[0], i[1], i[0] + v.getWidth(), i[1]
+ v.getHeight());
view_to_rect.put(v, _rect);
if (Build.VERSION.SDK_INT < 16) {
vto.removeGlobalOnLayoutListener(this);
} else {
vto.removeOnGlobalLayoutListener(this);
}
onPositionUpdate();
}
private void onPositionUpdate()
{
//do your work with positions
}