问题描述
我正在实现一个照片查看器,它允许用户从缩略图中以全屏模式查看照片.我目前的方法是向 WindowManager
添加膨胀视图.在膨胀视图中,有一个 ViewPager
允许用户切换图像.我收到错误java.lang.IllegalArgumentException: No view found for id"
I am implementing a photo viewer which allow user to view photos in full-screen mode from a thumbnail.
My current approach is adding inflated view to WindowManager
. In the inflated view, there is a ViewPager
allowing user switch images. And I got error "java.lang.IllegalArgumentException: No view found for id"
以下是详细信息(在 setActivity 方法中对视图进行膨胀,并在 openPhoto 方法中为 viewPager 设置适配器):
Here is the details (a view is inflated in setActivity method and setting adapter for viewPager in openPhoto method):
public class PhotoViewer {
private static final String TAG = "PhotoViewer";
private Activity parentActivity;
private FrameLayoutTouchListener windowView;
private RelativeLayout containerView;
private WindowManager.LayoutParams windowLayoutParams;
private PhotoViewerAdapter photoAdapter;
private ViewPager viewPager;
public PhotoViewer() {
super();
}
private static volatile PhotoViewer Instance = null;
/*inflate view here*/
public void setParentActivity(Activity activity) {
if (parentActivity == activity) {
return;
}
parentActivity = activity;
windowView = new FrameLayout(activity);
containerView = (RelativeLayout) LayoutInflater.from(activity)
.inflate(R.layout.fragment_photo_viewer, null);
containerView.setFocusable(false);
windowView.addView(containerView);
windowLayoutParams = new WindowManager.LayoutParams();
windowLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
windowLayoutParams.format = PixelFormat.TRANSLUCENT;
windowLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowLayoutParams.gravity = Gravity.TOP;
windowLayoutParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
viewPager = (ViewPager) containerView.findViewById(R.id.photo_viewer_view_pager);
}
/*set data and adapter for viewPager here*/
public void openPhoto (PhotoSupporter photoSupporter, int position){
try {
if (windowView.getParent() != null) {
WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
wm.removeView(windowView);
}
} catch (Exception e) {
Log.v(TAG, e.getMessage());
}
WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
wm.addView(windowView, windowLayoutParams);
this.photoSupporter = photoSupporter;
photoAdapter = new PhotoViewerAdapter(((FragmentActivity) parentActivity).getSupportFragmentManager(), photoSupporter);
viewPager.storeAdapter(photoAdapter);
viewPager.setCurrentItem(position);
}
/**
* Larger PhotoView
*
*
* **/
public static class PhotoViewerAdapter extends FragmentStatePagerAdapter {
private PhotoSupporter photoSupporter;
public PhotoViewerAdapter(FragmentManager fm, PhotoSupporter photoSupporter) {
super(fm);
this.photoSupporter = photoSupporter;
}
@Override
public Fragment getItem(int position) {
String src = null;
// get photo src
return PhotoViewFragment.newInstance(src);
}
@Override
public int getCount() {
Log.w(TAG, "size in adapter: " + photoSupporter.getSize());
return photoSupporter.getSize();
}
}
public static class PhotoViewFragment extends Fragment {
private String imagePath;
public PhotoViewFragment() {
}
public static PhotoViewFragment newInstance(String imagePath) {
PhotoViewFragment previewFragment = new PhotoViewFragment();
// put data
Bundle bundle = new Bundle();
bundle.putString("IMAGE_PATH",
imagePath);
previewFragment.setArguments(bundle);
return previewFragment;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imagePath = getArguments() != null ? getArguments().getString(
"IMAGE_PATH") : "";
Log.d("onCreate", imagePath);
}
/**
* The Fragment's UI is just a simple text view showing its instance
* number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ImageView imageView = new ImageView(getActivity());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
imageView.setLayoutParams(lp);
// set image by Picasso
Picasso picassoInstance = Picasso.with(getActivity());
picassoInstance.setIndicatorsEnabled(true);
picassoInstance.load(new File(imagePath))
.error(R.drawable.ic_picture_placeholder_light2)
.fit()
.centerInside()
.into(imageView);
return imageView;
}
}
}
这里是调用 PhotoViewer 方法的地方:
and here is where PhotoViewer's method is called:
public class PhotosFragment extends Fragment implements PhotoSupporter{
/*
....
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
showLoading();
photosGridview = (GridView) findViewById(R.id.group_photos_gridview);
if (listPhotos == null) {
listPhotos = new ArrayList<Photo>();
}
photoListAdapter = new PhotoListAdapter(listPhotos, getActivity());
photosGridview.setAdapter(photoListAdapter);
photosGridview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
PhotoViewer.getInstance().setParentActivity(getActivity());
PhotoViewer.getInstance().openPhoto(PhotosFragment.this, position);
}
});
}
@Override
public int getSize() {
return listPhotos == null ? 0 : listPhotos.size();
}
@Override
public Photo getPhotoItem(int position) {
return listPhotos.get(position);
}
}
这是包含 viewPager 的视图布局:
and here is layout of the view contaning viewPager:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/photo_viewer_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dark_background" >
</android.support.v4.view.ViewPager>
这里是logcat:
01-14 14:12:55.271: E/AndroidRuntime(11435): FATAL EXCEPTION: main
01-14 14:12:55.271: E/AndroidRuntime(11435): java.lang.IllegalArgumentException: No view found for id 0x7f0b00df (com.newsfeed.android:id/photo_viewer_view_pager) for fragment PhotoViewFragment{537b5ec4 #8 id=0x7f0b00df}
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.ja va:1088)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentSta tePagerAdapter.java:163)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.view.ViewPager.populate(ViewPager.java:1064)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.view.ViewPager.populate(ViewPager.java:911)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1432)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.View.measure(View.java:15172)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.View.measure(View.java:15172)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.View.measure(View.java:15172)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1848)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1100)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1273)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.Choreographer.doFrame(Choreographer.java:525)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.os.Handler.handleCallback(Handler.java:615)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.os.Handler.dispatchMessage(Handler.java:92)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.os.Looper.loop(Looper.java:137)
01-14 14:12:55.271: E/AndroidRuntime(11435): at android.app.ActivityThread.main(ActivityThread.java:4745)
01-14 14:12:55.271: E/AndroidRuntime(11435): at java.lang.reflect.Method.invokeNative(Native Method)
01-14 14:12:55.271: E/AndroidRuntime(11435): at java.lang.reflect.Method.invoke(Method.java:511)
01-14 14:12:55.271: E/AndroidRuntime(11435): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-14 14:12:55.271: E/AndroidRuntime(11435): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-14 14:12:55.271: E/AndroidRuntime(11435): at dalvik.system.NativeStart.main(Native Method)
这个问题有什么解决办法吗?非常感谢你们!
Any solution for this problem? Thank you guys so much!
推荐答案
我认为这是因为您直接通过 WindowManager 添加 ViewPager.这样做意味着它不会成为正常 Activity 视图层次结构的一部分(即装饰视图的子视图).Activity.findViewById
(使用装饰视图作为根遍历视图)将无法找到您的 ViewPager.
I think this is because you are adding your ViewPager directly via the WindowManager. Doing so means that it won't be part of the normal Activity view hierarchy (i.e. a child of the decor view). Activity.findViewById
(which traverses views using the decor view as the root) won't be able to locate your ViewPager.
ViewPager 适配器创建 Fragments 并使用 ViewPager (id) 作为容器.在创建 Fragment 时,Android 会通过 Activity.findViewById
查找此容器,但找不到它并因此引发此异常.
The ViewPager adapter creates Fragments and uses the ViewPager (id) as the container. When creating a Fragment, Android looks for this container via Activity.findViewById
, but won't be able to find it and so throws this exception.
听起来您想要某种显示在缩略图网格顶部的视图.您可以使用 正确样式 Dialog(Fragment) 来实现此目的.实施该观点的具体细节最好作为一个单独的问题提出.
It sounds like you want some kind of view that appears on top of the thumbnail grid. You could just use a properly styled Dialog(Fragment) to achieve this. The specifics of implementing that view would best be posed as a separate question.
这篇关于WindowManager 添加的视图上的 ViewPager 获取“java.lang.IllegalArgumentException:找不到 id 的视图"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!