我在我的项目中使用 Fragments 和带有 TabLayout 的 ViewPager,它在设备上不是 运行
i am using Fragments and a ViewPager with a TabLayout in my project , it is not running on devices
我与许多其他应用进行了比较。但我找不到我错了什么。
这是我所做的
[我更改了 gradle 版本 28.0.0-beta01 > 27.1.1,检查所有 xml 文件,清理并重建项目,我看到了很多关于 Viewpager 和 TabLayout 的视频。]
activity_main(TabLayout + ViewPager),
黑帮名单(ListView,id/list),
list_item(1 个图像视图,2 个文本视图)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the view pager that will allow the user to swipe between fragments
ViewPager viewPager = findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
CategoryAdapter adapter = new CategoryAdapter(this,getSupportFragmentManager());
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
TabLayout tabLayout= findViewById(R.id.tabs);
// Connect the tab layout with the view pager. This will
// 1. Update the tab layout when the view pager is swiped
// 2. Update the view pager when a tab is selected
// 3. Set the tab layout's tab names with the view pager's adapter's titles
// by calling onPageTitle()
tabLayout.setupWithViewPager(viewPager);
}
}
public class CategoryAdapter extends FragmentPagerAdapter {
private Context mContext;
public CategoryAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new YeoidoFragment();
case 1:
return new YeoidoFragment();
case 2:
return new YeoidoFragment();
default:
return null;
}
}
public int getCount() {
return 1;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return mContext.getString(R.string.yeouido_hangang_park);
case 1:
return mContext.getString(R.string.banpo_hangang_park);
case 2:
return mContext.getString(R.string.banpo_hangang_park);
default:
return null;
}
}
}
我正在使用相同的片段进行测试
public class Gang {
private int ImageResourceId;
private String Feature;
private String Explanation;
public Gang(int ImageResourceId, String Feature, String Explanation){
this.ImageResourceId = ImageResourceId;
this.Feature = Feature;
this.Explanation = Explanation;
}
public int getImageResourceId(){return ImageResourceId;}
public void setImageResourceId(int ImageResourceId){
this.ImageResourceId= ImageResourceId;
}
public String getFeature(){return Feature;}
public void setFeature(String Feature){
this.Feature = Feature;
}
public String getExplanation(){return Explanation;}
public void setExplanation(String Explanation){
this.Explanation = Explanation;
}
}
public class GangAdapter extends ArrayAdapter<Gang> {
public GangAdapter(Context context, ArrayList<Gang>gangs){
super(context, 0, gangs);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View listItemView = convertView;
if(listItemView==null){
listItemView= LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
Gang currentFeature = getItem(position);
ImageView spotImageView = listItemView.findViewById(R.id.Image);
spotImageView.setImageResource(currentFeature.getImageResourceId());
TextView featureTextView = listItemView.findViewById(R.id.where);
featureTextView.setText(currentFeature.getFeature());
TextView detailTextView = listItemView.findViewById(R.id.about);
detailTextView.setText(currentFeature.getExplanation());
return listItemView;
}
}
public class YeoidoFragment extends Fragment {
public YeoidoFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView= inflater.inflate(R.layout.ganglist, container, false);
final ArrayList<Gang> gangs = new ArrayList<>();
gangs.add(new Gang(R.drawable.yeouido1, getString(R.string.yeouido),getString(R.string.app_name)));
GangAdapter adapter = new GangAdapter(getActivity(), gangs);
ListView listView= rootView.findViewById(R.id.list);
listView.setAdapter(adapter);
return rootView;
}
}
来自 logcat
08-06 21:32:41.805 8882-8882/com.example.android.hangangabout
E/Zygote: isWhitelistProcess - Process is Whitelisted 08-06
21:32:41.806 8882-8882/com.example.android.hangangabout W/SELinux:
SELinux selinux_android_compute_policy_index : Policy Index[2],
Con:u:r:zygote:s0 RAM:SEPF_SM-G950N_8.0.0_0005, [-1 -1 -1 -1 0 1]
08-06 21:32:41.807 8882-8882/com.example.android.hangangabout
I/SELinux: SELinux: seapp_context_lookup: seinfo=untrusted,
level=s0:c512,c768, pkgname=com.example.android.hangangabout 08-06
21:32:41.810 8882-8882/com.example.android.hangangabout I/zygote64:
Late-enabling -Xcheck:jni 08-06 21:32:41.878
8882-8882/com.example.android.hangangabout D/ActivityThread: Added
TimaKeyStore provider 08-06 21:32:42.026
8882-8924/com.example.android.hangangabout I/vndksupport: sphal
namespace is not configured for this process. Loading
/vendor/lib64/egl/libGLES_mali.so from the current namespace instead.
08-06 21:32:42.036 8882-8882/com.example.android.hangangabout
I/InstantRun: starting instant run server: is main process 08-06
21:32:42.045 8882-8924/com.example.android.hangangabout D/libEGL:
loaded /vendor/lib64/egl/libGLES_mali.so 08-06 21:32:42.990
8882-9058/com.example.android.hangangabout D/OpenGLRenderer: HWUI GL
Pipeline 08-06 21:32:43.001 8882-8882/com.example.android.hangangabout
D/ViewRootImpl@c5bf86a[MainActivity]: setView =
DecorView@4d5415b[MainActivity] TM=true MM=false 08-06 21:32:43.011
8882-8882/com.example.android.hangangabout
D/ViewRootImpl@c5bf86a[MainActivity]: dispatchAttachedToWindow 08-06
21:32:43.067 8882-8882/com.example.android.hangangabout V/Surface:
sf_framedrop debug : 0x4f4c, game : false, logging : 0 08-06
21:32:43.068 8882-8882/com.example.android.hangangabout
D/ViewRootImpl@c5bf86a[MainActivity]: Relayout returned:
old=[0,0][0,0] new=[0,0][1440,2960] result=0x7 surface={valid=true
539904405504} changed=true 08-06 21:32:43.091
8882-9058/com.example.android.hangangabout I/OpenGLRenderer:
Initialized EGL, version 1.4 08-06 21:32:43.091
8882-9058/com.example.android.hangangabout D/OpenGLRenderer: Swap
behavior 2 08-06 21:32:43.100
8882-9058/com.example.android.hangangabout D/libGLESv1: STS_GLApi :
DTS, ODTC are not allowed for Package :
com.example.android.hangangabout 08-06 21:32:43.101
8882-9058/com.example.android.hangangabout D/mali_winsys: EGLint
new_window_surface(egl_winsys_display *, void *, EGLSurface,
EGLConfig, egl_winsys_surface **, egl_color_buffer_format *,
EGLBoolean) returns 0x3000, [1440x2960]-format:1 08-06 21:32:43.101
8882-9058/com.example.android.hangangabout D/OpenGLRenderer:
eglCreateWindowSurface = 0x7dbb41daf0 08-06 21:32:43.458
8882-8882/com.example.android.hangangabout D/AbsListView: in onLayout
changed 08-06 21:32:43.497 8882-8882/com.example.android.hangangabout
D/AndroidRuntime: Shutting down VM 08-06 21:32:43.516
8882-8882/com.example.android.hangangabout E/AndroidRuntime: FATAL
EXCEPTION: main
Process: com.example.android.hangangabout, PID: 8882
java.lang.RuntimeException: Canvas: trying to draw too large(132710400bytes) bitmap.
at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)
at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529)
at android.view.View.getDrawableRenderNode(View.java:20627)
at android.view.View.drawBackground(View.java:20563)
at android.view.View.draw(View.java:20343)
at android.view.View.updateDisplayListIfDirty(View.java:19297)
at android.view.View.draw(View.java:20075)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19288)
at android.view.View.draw(View.java:20075)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19288)
at android.view.View.draw(View.java:20075)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19288)
at android.view.View.draw(View.java:20075)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19288)
at android.view.View.draw(View.java:20075)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.draw(View.java:20355)
at com.android.internal.policy.DecorView.draw(DecorView.java:979)
at android.view.View.updateDisplayListIfDirty(View.java:19297)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3451)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3238)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2773)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1742)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7763)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
我认为 int getCount() 应该 return 3
您应该在
上定义或创建数组列表适配器
public void onViewCreated(View view, @Nullable Bundle saveInstanceState) {
}
由于 logcat 正在报告,您正在尝试将大位图绘制到 canvas 中:
FATAL EXCEPTION: main Process: com.example.android.hangangabout, PID: 8882 java.lang.RuntimeException: Canvas: trying to draw too large(132710400bytes) bitmap.
这超过了 132 兆字节!您应该在绘制之前缩放图像。一般来说,不需要这么大的位图,因为您的设备没有足够的像素来显示它。
此外,拥有如此大的对象很危险,因为您的应用程序的 RAM 限制受设备限制(限制取决于设备)。您的应用通常只能使用 32mb 的内存。
我与许多其他应用进行了比较。但我找不到我错了什么。
这是我所做的
[我更改了 gradle 版本 28.0.0-beta01 > 27.1.1,检查所有 xml 文件,清理并重建项目,我看到了很多关于 Viewpager 和 TabLayout 的视频。]
activity_main(TabLayout + ViewPager), 黑帮名单(ListView,id/list), list_item(1 个图像视图,2 个文本视图)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the view pager that will allow the user to swipe between fragments
ViewPager viewPager = findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
CategoryAdapter adapter = new CategoryAdapter(this,getSupportFragmentManager());
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
TabLayout tabLayout= findViewById(R.id.tabs);
// Connect the tab layout with the view pager. This will
// 1. Update the tab layout when the view pager is swiped
// 2. Update the view pager when a tab is selected
// 3. Set the tab layout's tab names with the view pager's adapter's titles
// by calling onPageTitle()
tabLayout.setupWithViewPager(viewPager);
}
}
public class CategoryAdapter extends FragmentPagerAdapter {
private Context mContext;
public CategoryAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new YeoidoFragment();
case 1:
return new YeoidoFragment();
case 2:
return new YeoidoFragment();
default:
return null;
}
}
public int getCount() {
return 1;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return mContext.getString(R.string.yeouido_hangang_park);
case 1:
return mContext.getString(R.string.banpo_hangang_park);
case 2:
return mContext.getString(R.string.banpo_hangang_park);
default:
return null;
}
}
}
我正在使用相同的片段进行测试
public class Gang {
private int ImageResourceId;
private String Feature;
private String Explanation;
public Gang(int ImageResourceId, String Feature, String Explanation){
this.ImageResourceId = ImageResourceId;
this.Feature = Feature;
this.Explanation = Explanation;
}
public int getImageResourceId(){return ImageResourceId;}
public void setImageResourceId(int ImageResourceId){
this.ImageResourceId= ImageResourceId;
}
public String getFeature(){return Feature;}
public void setFeature(String Feature){
this.Feature = Feature;
}
public String getExplanation(){return Explanation;}
public void setExplanation(String Explanation){
this.Explanation = Explanation;
}
}
public class GangAdapter extends ArrayAdapter<Gang> {
public GangAdapter(Context context, ArrayList<Gang>gangs){
super(context, 0, gangs);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View listItemView = convertView;
if(listItemView==null){
listItemView= LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
Gang currentFeature = getItem(position);
ImageView spotImageView = listItemView.findViewById(R.id.Image);
spotImageView.setImageResource(currentFeature.getImageResourceId());
TextView featureTextView = listItemView.findViewById(R.id.where);
featureTextView.setText(currentFeature.getFeature());
TextView detailTextView = listItemView.findViewById(R.id.about);
detailTextView.setText(currentFeature.getExplanation());
return listItemView;
}
}
public class YeoidoFragment extends Fragment {
public YeoidoFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView= inflater.inflate(R.layout.ganglist, container, false);
final ArrayList<Gang> gangs = new ArrayList<>();
gangs.add(new Gang(R.drawable.yeouido1, getString(R.string.yeouido),getString(R.string.app_name)));
GangAdapter adapter = new GangAdapter(getActivity(), gangs);
ListView listView= rootView.findViewById(R.id.list);
listView.setAdapter(adapter);
return rootView;
}
}
来自 logcat
08-06 21:32:41.805 8882-8882/com.example.android.hangangabout E/Zygote: isWhitelistProcess - Process is Whitelisted 08-06 21:32:41.806 8882-8882/com.example.android.hangangabout W/SELinux: SELinux selinux_android_compute_policy_index : Policy Index[2], Con:u:r:zygote:s0 RAM:SEPF_SM-G950N_8.0.0_0005, [-1 -1 -1 -1 0 1] 08-06 21:32:41.807 8882-8882/com.example.android.hangangabout I/SELinux: SELinux: seapp_context_lookup: seinfo=untrusted, level=s0:c512,c768, pkgname=com.example.android.hangangabout 08-06 21:32:41.810 8882-8882/com.example.android.hangangabout I/zygote64: Late-enabling -Xcheck:jni 08-06 21:32:41.878 8882-8882/com.example.android.hangangabout D/ActivityThread: Added TimaKeyStore provider 08-06 21:32:42.026 8882-8924/com.example.android.hangangabout I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/egl/libGLES_mali.so from the current namespace instead. 08-06 21:32:42.036 8882-8882/com.example.android.hangangabout I/InstantRun: starting instant run server: is main process 08-06 21:32:42.045 8882-8924/com.example.android.hangangabout D/libEGL: loaded /vendor/lib64/egl/libGLES_mali.so 08-06 21:32:42.990 8882-9058/com.example.android.hangangabout D/OpenGLRenderer: HWUI GL Pipeline 08-06 21:32:43.001 8882-8882/com.example.android.hangangabout D/ViewRootImpl@c5bf86a[MainActivity]: setView = DecorView@4d5415b[MainActivity] TM=true MM=false 08-06 21:32:43.011 8882-8882/com.example.android.hangangabout D/ViewRootImpl@c5bf86a[MainActivity]: dispatchAttachedToWindow 08-06 21:32:43.067 8882-8882/com.example.android.hangangabout V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0 08-06 21:32:43.068 8882-8882/com.example.android.hangangabout D/ViewRootImpl@c5bf86a[MainActivity]: Relayout returned: old=[0,0][0,0] new=[0,0][1440,2960] result=0x7 surface={valid=true 539904405504} changed=true 08-06 21:32:43.091 8882-9058/com.example.android.hangangabout I/OpenGLRenderer: Initialized EGL, version 1.4 08-06 21:32:43.091 8882-9058/com.example.android.hangangabout D/OpenGLRenderer: Swap behavior 2 08-06 21:32:43.100 8882-9058/com.example.android.hangangabout D/libGLESv1: STS_GLApi : DTS, ODTC are not allowed for Package : com.example.android.hangangabout 08-06 21:32:43.101 8882-9058/com.example.android.hangangabout D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000, [1440x2960]-format:1 08-06 21:32:43.101 8882-9058/com.example.android.hangangabout D/OpenGLRenderer: eglCreateWindowSurface = 0x7dbb41daf0 08-06 21:32:43.458 8882-8882/com.example.android.hangangabout D/AbsListView: in onLayout changed 08-06 21:32:43.497 8882-8882/com.example.android.hangangabout D/AndroidRuntime: Shutting down VM 08-06 21:32:43.516 8882-8882/com.example.android.hangangabout E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.hangangabout, PID: 8882 java.lang.RuntimeException: Canvas: trying to draw too large(132710400bytes) bitmap. at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229) at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97) at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529) at android.view.View.getDrawableRenderNode(View.java:20627) at android.view.View.drawBackground(View.java:20563) at android.view.View.draw(View.java:20343) at android.view.View.updateDisplayListIfDirty(View.java:19297) at android.view.View.draw(View.java:20075) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19288) at android.view.View.draw(View.java:20075) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19288) at android.view.View.draw(View.java:20075) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19288) at android.view.View.draw(View.java:20075) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19288) at android.view.View.draw(View.java:20075) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.draw(View.java:20355) at com.android.internal.policy.DecorView.draw(DecorView.java:979) at android.view.View.updateDisplayListIfDirty(View.java:19297) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3451) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3238) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2773) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1742) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7763) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911) at android.view.Choreographer.doCallbacks(Choreographer.java:723) at android.view.Choreographer.doFrame(Choreographer.java:658) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6938) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
我认为 int getCount() 应该 return 3
您应该在
上定义或创建数组列表适配器public void onViewCreated(View view, @Nullable Bundle saveInstanceState) {
}
由于 logcat 正在报告,您正在尝试将大位图绘制到 canvas 中:
FATAL EXCEPTION: main Process: com.example.android.hangangabout, PID: 8882 java.lang.RuntimeException: Canvas: trying to draw too large(132710400bytes) bitmap.
这超过了 132 兆字节!您应该在绘制之前缩放图像。一般来说,不需要这么大的位图,因为您的设备没有足够的像素来显示它。
此外,拥有如此大的对象很危险,因为您的应用程序的 RAM 限制受设备限制(限制取决于设备)。您的应用通常只能使用 32mb 的内存。