GVKun编程网logo

android – getWidth在Fragment中返回0,getPaddingLeft返回非零(android gettext返回类型)

11

在本文中,您将会了解到关于android–getWidth在Fragment中返回0,getPaddingLeft返回非零的新资讯,同时我们还将为您解释androidgettext返回类型的相关在本文

在本文中,您将会了解到关于android – getWidth在Fragment中返回0,getPaddingLeft返回非零的新资讯,同时我们还将为您解释android gettext返回类型的相关在本文中,我们将带你探索android – getWidth在Fragment中返回0,getPaddingLeft返回非零的奥秘,分析android gettext返回类型的特点,并给出一些关于android 3.0中的getSupportFragmentManager()与getFragmentManager()、Android Fragment getArguments()返回null、android FragmentpagerAdapter和FragmentStatePagerAdapter的区别、Android FragmentPagerAdapter在切换fragment时,怎么有些乱?的实用技巧。

本文目录一览:

android – getWidth在Fragment中返回0,getPaddingLeft返回非零(android gettext返回类型)

android – getWidth在Fragment中返回0,getPaddingLeft返回非零(android gettext返回类型)

我正在尝试将我的 Android应用程序转换为Fragments以支持多种屏幕尺寸并正确使用新的ICS选项卡.以前我使用了onWindowFocusChanged()方法并在其中运行了以下代码 – 基本上这在我的布局创建后做了一些动态格式化.
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {

LinearLayout theLayout = (LinearLayout)inflater.inflate(R.layout.tab_frag2_layout,container,false);

getWidthEditButton = (ImageButton) theLayout.findViewById(R.id.buttonEditPoints);
buttonAddPointsManual = (ImageView) theLayout.findViewById(R.id.buttonAddPointsManual);

linearPointsUsed = (LinearLayout) theLayout.findViewById(R.id.linearLayoutPointsUsed);

int paddingLeftForTracker = linearPointsUsed.getPaddingLeft();
int paddingRightForTracker = getWidthEditButton.getWidth();

linearPointsUsed.setPadding(paddingLeftForTracker,paddingRightForTracker,0);
}

现在我已经转移到Fragments并且由于某种原因我的paddingRightForTracker返回0.我之前遇到了一个问题,我试图过早地获得宽度,因此我之前转移到onWindowFocusChanged,但这不适用于Fragments.奇怪的是paddingLeftForTracker实际上返回一个非零值.

如果我手动设置paddingRightForTracker,则会发生更改,因此我知道代码正在运行.只是无法弄清楚为什么我的getWidth返回0.

任何帮助将不胜感激.

解决方法

您可以尝试在onActivityCreated()中执行此操作.因此,您可以在onCreateView中保存对这些视图的引用,然后在onActivityCreated()中访问它们.我认为当你试图访问它时,视图没有完成,这就是它没有返回宽度的原因.

http://developer.android.com/reference/android/app/Fragment.html#onActivityCreated(android.os.Bundle)

好的,所以我发现了另一种获得宽度的方法.我也无法在onViewCreated,onCreateView和onResume上获得按钮宽度.我发现了这个,尝试过它,它返回了一个值,所以也许它对你有用!

How to get height and width of Button

ViewTreeObserver vto = button.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
        width = button.getWidth();
        height = button.getHeight(); 
    }
});

仅供参考,我在onResume上运行了这段代码,所以我不确定它能在哪里工作.

android 3.0中的getSupportFragmentManager()与getFragmentManager()

android 3.0中的getSupportFragmentManager()与getFragmentManager()

在 android.support.v4.app.FragmentManager的文档中:

“框架的FragmentManager的静态库支持版本.用于编写在Android 3.0之前的平台上运行的应用程序.在Android 3.0或更高版本上运行时,仍然使用此实现;它不会尝试切换到框架的实现.请参阅用于类概述的框架SDK文档.“

那么,我是否需要在运行时进行检查并使用适当的FragmentManager来运行应用程序的Android版本?即如果在android 3.0而不是getSupportFragmentManager()上调用getFragmentManager()

解决方法

只要您导入了支持库,在Android 3.0上使用getSupportFragmentManager()就没有错.如果你想对SDKs 11使用getFragmentManager(),那就去吧;请记住,如果使用版本检查,您可能会使用大量代码.

Android Fragment getArguments()返回null

Android Fragment getArguments()返回null

正如标题所示.
我从这里下载了片段代码,http://developer.android.com/shareables/training/FragmentBasics.zip.
这是来自Android官方开发者网站的片段示例. http://developer.android.com/training/basics/fragments/fragment-ui.html

这是MainActivity.java的onCreate():

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.news_articles);

    // Check whether the activity is using the layout version with
    // the fragment_container FrameLayout. If so, we must add the first fragment
    if (findViewById(R.id.fragment_container) != null) {

        // However, if we're being restored from a prevIoUs state,
        // then we don't need to do anything and should return or else
        // we Could end up with overlapping fragments.
        if (savedInstanceState != null) {
            return;
        }

        // Create an instance of ExampleFragment
        HeadlinesFragment fragment = new HeadlinesFragment();

        // In case this activity was started with special instructions from an Intent,
        // pass the Intent's extras to the fragment as arguments
        //fragment.setArguments(getIntent().getExtras());
        Bundle args= new Bundle();
        args.putString("category", "clothes");
        args.putString("item", "shirts");
        fragment.setArguments(args);

        // Add the fragment to the 'fragment_container' FrameLayout
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, fragment).commit();
    }
}

和HeadlinesFragment.java的onCreate():

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // We need to use a different list item layout for devices older than Honeycomb
    int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
            android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1;

    Bundle args = getArguments();
    if (args == null) {
        Toast.makeText(getActivity(), "arguments is null " , Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(getActivity(), "text " + args , Toast.LENGTH_LONG).show();
    }        

    // Create an array adapter for the list view, using the Ipsum headlines array
    setlistadapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines));

}

我在这里读了几个QA,比如这个@L_301_2@,以及与setArguments()和getArguments()相关的许多其他QA,但我仍然被卡住了.

我已经将Bundle和Toast代码移动到onAttach()和onCreateView(),但没有用.我的代码有什么问题?我想我错过了什么,但不知道它是什么.
请帮忙!谢谢.

编辑:
我会更清楚地表明我的意图.在我下载的FragmentBasic中,有MainActivity.java,HeadlinesFragment.java和ArticlesFragment.java.从MainActivity.java到ArticlesFragment.java的“通信”不是问题.我想要的是将数据从MainActivity.java发送到HeadlinesFragment.java.他们的联系是这样的:

--------------------------------------
| MainActivity <-> HeadlinesFragment |
|      |                             |
|      |>> ArticlesFragment          |
--------------------------------------

HeadlinesFragment正在运行时运行.

*当使用带有<的Android小工具时,这些代码可以正常工作600px宽度.但是在平板电脑上使用时不起作用(> = 600px),正如下面@ Tesla1984所证明的那样.但我想要的是小工具< 600px和小工具> 600px的.

解决方法:

@tonny

我下载了FragmentBasics.zip.我只更改参数名称.代码和结果图片.

主要活动

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.news_articles);

    // Check whether the activity is using the layout version with
    // the fragment_container FrameLayout. If so, we must add the first fragment
    if (findViewById(R.id.fragment_container) != null) {

        // However, if we're being restored from a prevIoUs state,
        // then we don't need to do anything and should return or else
        // we Could end up with overlapping fragments.
        if (savedInstanceState != null) {
            return;
        }

        // Create an instance of ExampleFragment
        HeadlinesFragment fragment = new HeadlinesFragment();

        // In case this activity was started with special instructions from an Intent,
        // pass the Intent's extras to the fragment as arguments
//            firstFragment.setArguments(getIntent().getExtras());
        //test
        Bundle args= new Bundle();
        args.putString("category", "clothes");
        args.putString("item", "shirts");
        fragment.setArguments(args);

        // Add the fragment to the 'fragment_container' FrameLayout
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, fragment).commit();
    }
}

HeadlinesFragment

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // We need to use a different list item layout for devices older than Honeycomb
    int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
            android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1;

    Bundle args = getArguments();
    if (args == null) {
        Toast.makeText(getActivity(), "arguments is null " , Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(getActivity(), "text " + args , Toast.LENGTH_LONG).show();
    }    

    // Create an array adapter for the list view, using the Ipsum headlines array
    setlistadapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines));
}

这是结果

android FragmentpagerAdapter和FragmentStatePagerAdapter的区别

android FragmentpagerAdapter和FragmentStatePagerAdapter的区别

1.FragmentPagerAdapter
FragmentPagerAdapter 继承自 PagerAdapter。相比通用的 PagerAdapter,该类更专注于每一页均为 Fragment 的情况。如文档所述,该类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。FragmentPagerAdapter 重载实现了几个必须的函数,因此来自 PagerAdapter 的函数,我们只需要实现 getCount(),即可。且,由于 FragmentPagerAdapter.instantiateItem() 的实现中,调用了一个新增的虚函数 getItem(),因此,我们还至少需要实现一个 getItem()。因此,总体上来说,相对于继承自 PagerAdapter,更方便一些。

  • getItem()
    • 该类中新增的一个虚函数。函数的目的为生成新的 Fragment 对象。重载该函数时需要注意这一点。在需要时,该函数将被 instantiateItem() 所调用。
    • 如果需要向 Fragment 对象传递相对静态的数据时,我们一般通过 Fragment.setArguments() 来进行,这部分代码应当放到 getItem()。它们只会在新生成 Fragment 对象时执行一遍。
    • 如果需要在生成 Fragment 对象后,将数据集里面一些动态的数据传递给该 Fragment,那么,这部分代码不适合放到 getItem() 中。因为当数据集发生变化时,往往对应的 Fragment 已经生成,如果传递数据部分代码放到了 getItem() 中,这部分代码将不会被调用。这也是为什么很多人发现调用 PagerAdapter.notifyDataSetChanged() 后,getItem() 没有被调用的一个原因。
  • instantiateItem()
    • 函数中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。
    • FragmentPagerAdapter 会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法
    • 如果需要在生成 Fragment 对象后,将数据集中的一些数据传递给该 Fragment,这部分代码应该放到这个函数的重载里。在我们继承的子类中,重载该函数,并调用 FragmentPagerAdapter.instantiateItem() 取得该函数返回 Fragment 对象,然后,我们该 Fragment 对象中对应的方法,将数据传递过去,然后返回该对象。
    • 否则,如果将这部分传递数据的代码放到 getItem()中,在 PagerAdapter.notifyDataSetChanged() 后,这部分数据设置代码将不会被调用。
  • destroyItem()
    • 该函数被调用后,会对 Fragment 进行 FragmentTransaction.detach()。这里不是 remove(),只是 detach(),因此 Fragment 还在 FragmentManager 管理中,Fragment 所占用的资源不会被释放。
  • 2.FragmentStatePagerAdapter
    FragmentStatePagerAdapter 和前面的 FragmentPagerAdapter 一样,是继承子 PagerAdapter。但是,和 FragmentPagerAdapter 不一样的是,正如其类名中的 ''State'' 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。

    • getItem()
      • 一个该类中新增的虚函数。
      • 函数的目的为生成新的 Fragment 对象。
      • Fragment.setArguments() 这种只会在新建 Fragment 时执行一次的参数传递代码,可以放在这里。
      • 由于 FragmentStatePagerAdapter.instantiateItem() 在大多数情况下,都将调用 getItem() 来生成新的对象,因此如果在该函数中放置与数据集相关的 setter 代码,基本上都可以在 instantiateItem() 被调用时执行,但这和设计意图不符。毕竟还有部分可能是不会调用 getItem() 的。因此这部分代码应该放到 instantiateItem() 中。
    • instantiateItem()
      • 除非碰到 FragmentManager 刚好从 SavedState 中恢复了对应的 Fragment 的情况外,该函数将会调用 getItem() 函数,生成新的 Fragment 对象。新的对象将被 FragmentTransaction.add()。
      • FragmentStatePagerAdapter 就是通过这种方式,每次都创建一个新的 Fragment,而在不用后就立刻释放其资源,来达到节省内存占用的目的的。
    • destroyItem()
      • 将 Fragment 移除,即调用 FragmentTransaction.remove(),并释放其资源。

本文同步分享在 博客“xiangzhihong8”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

Android FragmentPagerAdapter在切换fragment时,怎么有些乱?

Android FragmentPagerAdapter在切换fragment时,怎么有些乱?

我用FragmentPagerAdapter 进行fragment切换,一共是5个fragment。

一开始的时候,是把前3个create了,我切换显示第2个的时候,程序把第4个第5个fragment进行了create;

切换显示第5个的时候,第2个fragment进行了onPause、onDestroyView等操作;第5个本身的onStart却没有被调用;

再切换显示第2个,第5个进行了onDestroyView等操作;第1个又进行了createView的操作;第2个自身的onStart也没有被调用;

=============================================================

我本来想在onStart和onPause里面,加一个变量,用于判断当前的fragment是不是正在显示,从而进行一些操作 ;这样一看,根本无法实现。

 

今天关于android – getWidth在Fragment中返回0,getPaddingLeft返回非零android gettext返回类型的分享就到这里,希望大家有所收获,若想了解更多关于android 3.0中的getSupportFragmentManager()与getFragmentManager()、Android Fragment getArguments()返回null、android FragmentpagerAdapter和FragmentStatePagerAdapter的区别、Android FragmentPagerAdapter在切换fragment时,怎么有些乱?等相关知识,可以在本站进行查询。

本文标签: