- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 fragment 可以在细节 Activity 中(如果设备的视口(viewport)很小)或在主要 Activity 中(如果视口(viewport)很大,例如平板电脑)。
fragment 内部有一个 ImageView,我需要根据 fragment 的宽度调整其大小。我做了一些研究,发现实现此目的的“规范”方法是向 viewtreeobserver 添加一个监听器。但是,由于某种原因,它不起作用:
这是我的 fragment :
public class MediaDetailFragment extends Fragment implements DetailsMvpView {
private static final String RESOURCE = "resource";
@Inject DetailPresenter mPresenter;
@BindView(R.id.media_image_flipper)
ViewFlipper mImageFlipper;
@BindView(R.id.title_textview)
TextView mTitleTextView;
@BindView(R.id.button_share)
ImageButton mShare;
@BindView(R.id.button_trailers) ImageButton mTrailers;
@BindView(R.id.keyword_recyclerview)
RecyclerView mKeywordRecyclerView;
@BindView(R.id.overview_content_textview) TextView mOverviewTextView;
@BindView(R.id.main_image_holder) ViewGroup mImageHolder;
@BindView(R.id.parent_cardview)
CardView mParentCardView;
@BindString(R.string.youtube_base_url) String mYoutubeUrl;
@BindBool(R.bool.isTablet) boolean mIsTablet;
private Media mMedia;
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
public static MediaDetailFragment insertOnTarget(AppCompatActivity activity, int target, Media media) {
MediaDetailFragment fragment = MediaDetailFragment.instantiateWithArguments(media);
FragmentManager fm = activity.getSupportFragmentManager();
fm.beginTransaction()
.replace(target, fragment)
.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right)
.commit();
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMedia = getArguments().getParcelable(RESOURCE);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.media_details_fragment, container, false);
((BaseActivity)getActivity()).activityComponent().inject(this);
ButterKnife.bind(this, rootView);
getActivity().getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
mTitleTextView.setText(mMedia.title());
mOverviewTextView.setText(mMedia.overview());
mKeywordRecyclerView.setAdapter(new KeywordAdapter(getContext()));
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View view = getView();
if (view == null) return;
view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
if (mIsTablet) {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(view.getWidth(), ViewUtil.PORTRAIT);
} else {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(mDisplayMetrics.widthPixels, ViewUtil.PORTRAIT);
}
});
}
@Override
public void onStart() {
super.onStart();
mShare.setOnClickListener(v -> {startActivity(new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_TEXT, String.format(mYoutubeUrl, mMedia.overview())));});
mTrailers.setOnClickListener(v -> mPresenter.loadMovies(mMedia.id()));
mPresenter.attachView(this);
mPresenter.loadImages(mMedia.id());
mPresenter.loadKeywords(mMedia.id());
}
@Override
public void onStop() {
mPresenter.detachView();
super.onStop();
}
@Override
public void showImages(String images) {
ImageView imageView = new ImageView(getContext());
ViewUtil.loadImage(images, imageView, getContext(), true, true);
mImageFlipper.addView(imageView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
@Override
public void showKeywords(List<String> keywords) {
((KeywordAdapter) mKeywordRecyclerView.getAdapter()).setKeywords(keywords);
}
@Override
public void showVideos(List<Video> videos) {
TrailerDialogFragment.newInstance(videos).show(getFragmentManager(), null);
}
@Override
public void showError() {
}
private static MediaDetailFragment instantiateWithArguments(Media media) {
Bundle bundle = new Bundle();
bundle.putParcelable(RESOURCE, media);
MediaDetailFragment fragment = new MediaDetailFragment();
fragment.setArguments(bundle);
return fragment;
}
}
我在 onactivitycreated 回调上调用附加监听器。
你能帮我找出丢失的部分吗?
谢谢。
最佳答案
出于某些奇怪的原因,当我将代码包装在可运行对象中时,代码可以正常工作。这是我的解决方案:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View view = getView();
if (view == null) return;
view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
view.post(() -> {
if (mIsTablet) {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(view.getWidth(), ViewUtil.PORTRAIT);
} else {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(mDisplayMetrics.widthPixels, ViewUtil.PORTRAIT);
}
});
});
}
我终于可以解决它,但我不明白为什么。如果你们中有人知道为什么会发生这种情况,请告诉我。
关于android - 获取 fragment 宽度,viewtreeobserver 监听器不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39004023/
几个月以来,我在 Crashlytics 和 Google Play 控制台中遇到了 IndexOutOfBoundsException。我无法弄清楚它到底发生在哪里,因为堆栈跟踪仅列出了框架代码(请
我在 onCreate 中将一个 ViewTreeObserver 添加到我的 fragment 之一: view.getViewTreeObserver().addOnGlobalLayoutLi
我正在开发一个应用程序,该应用程序监听 View 事件,例如使用 ViewTreeObserver 绘制的滚动和布局。 ViewTreeObserver 有一种方法可以在执行任何操作之前检查它是否还活
我在 onCreate() 方法中使用 ViewTreeObserver.OnGlobalLayoutListener 来获取布局的宽度。它工作得很好,但是当我在 onGlobalLayout() 中
如何在 Android 的服务中实现 ViewTreeObserver.OnWindowFocusChangeListener 。当我在 java 文件中使用该代码时,它没有显示任何类型的错误。还有其
为什么我们要使用ViewTreeObserver,谁能解释一下? 在下面的代码中,creditsView 是 TextView 对象。通过这整个代码,我明白“这是根据条件隐藏一些文本”,但唯一的问题是
我正在使用 LeakCanary 1.3.1-SNAPSHOT。我发现了有关 ViewTreeObserver.OnScrollChangedListener 设置的漏洞,我按照以下代码修复了它:
我在使用 ViewTreeObserver 时遇到了很大的困难。在一段不可预知的时间段内一切正常,然后监听器不再运行。这肯定是因为文档中写的:The returned ViewTreeObserver
我已经在使用 ViewTreeObserver 的 Activity 中没有问题,但在这种情况下我没有得到 onGlobalLayout 回调。 由于我在执行 http API 调用后获得了 View
我正在使用 OnGlobalLayoutListener 监听 View 的布局更改: view.getViewTreeObserver().addOnGlobalLayoutListener(myL
我需要监听一个确切的全局布局事件来初始设置正确的滚动位置。在搜索了一下为什么我对 scrollTo(x,y) 的调用似乎被忽略后,我发现只有知道整个布局后才能以有意义的方式调用这些。所以我正在注册一个
我有一个在我的方法中创建的 HashMap final HashMap listViewItemBounds = new HashMap(); 将可见 View 的所有边界保存在 ListView 中
我在两个 TextView 的父 View 上使用 viewTreeObserver.addOnGlobalLayoutListener , onGlobalLayout 以获得一个的宽度和另一个的高
假设我需要获取和设置 View 的高度。在 Android 中,众所周知只有在绘制后才能获得 View 高度。如果您使用的是 Java,有很多答案,最著名的方法之一就是下面这个,摘自 this ans
如何让观察者进入监听者?示例: ViewTreeObserver myObserver = myLayout.getViewTreeObserver(); myObserver.addOnPreDra
我有一个 fragment 可以在细节 Activity 中(如果设备的视口(viewport)很小)或在主要 Activity 中(如果视口(viewport)很大,例如平板电脑)。 fragmen
在MainActivity您单击相机按钮,拍照,然后图像显示在 PreviewActivity 上然后我应该得到 imageView 的宽度和高度. 我试图显示一个 log当我触摸屏幕时显示高度值的消
我有一个带有 webview 和按钮的布局。该按钮是可见的,但一旦滚动 web View 就会变得可见。我正在使用 ViewTreeObserver,但由于某种原因,未调用 onScrollChang
我在 OnCreate 方法中使用 ViewTreeObserver 来获取我的工具栏和底部布局的高度,但我仍然得到 0 高度,为什么?我做错了什么吗? 我是这样调用的: ViewTreeObserv
我有两个表:TableA 和 TableB。 TableA 的第一行高度为 22,TableB 的第一行高度为 77。我想将 TableA 的第一行等同于 TableB 的第一行,为此我使用以下代码:
我是一名优秀的程序员,十分优秀!