代码之家  ›  专栏  ›  技术社区  ›  Kenny

findViewById在片段中,未放入onCreateView

  •  1
  • Kenny  · 技术社区  · 7 年前

    我想知道是否可以在onCreateView方法之外设置TextView。

    以下是在Android studio上成功运行的代码

    public class TabMatchFragmentOdd extends Fragment {
        TextView Home, Away;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.tab_match_odd, container, false);
            Home = (TextView) v.findViewById(R.id.homename);
            Away = (TextView) v.findViewById(R.id.awayname);
            getIncomingIntent();
    
            return v;
        }
    
        private void getIncomingIntent() {
            if (getActivity().getIntent().hasExtra("HomeName") && getActivity().getIntent().hasExtra("AwayName")) {
                String HomeName = getActivity().getIntent().getStringExtra("HomeName").toString();
                String AwayName = getActivity().getIntent().getStringExtra("AwayName").toString();
                setContent(HomeName,AwayName);        
            } else {
                Toast.makeText(getActivity(), "No", Toast.LENGTH_SHORT).show();
            }
        }
    
        private void setContent(String home, String away) { 
            Home.setText(home);
            Away.setText(away);
        }
    }
    

    但我想通过特定的方法使我的代码更加清晰

    我可以用上述类似的方法吗?

    public class TabMatchFragmentOdd extends Fragment {
        TextView Home, Away;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v;
             v = inflater.inflate(R.layout.tab_match_odd, container, false);
            getIncomingIntent();
            return v;
    
        }
    
        private void getIncomingIntent() {
            if(getActivity().getIntent().hasExtra("HomeName")&&getActivity().getIntent().hasExtra("AwayName")) {
                String HomeName = getActivity().getIntent().getStringExtra("HomeName").toString();
                String AwayName = getActivity().getIntent().getStringExtra("AwayName").toString();
                setContent(HomeName,AwayName);         
            }else{
                Toast.makeText(getActivity(), "No:", Toast.LENGTH_SHORT).show();
            }
        }
    
        private void setContent(String home, String away) {
            Home = (TextView) getActivity().findViewById(R.id.homename);
            Away = (TextView) getActivity().findViewById(R.id.awayname);      
            Home.setText(home);
            Away.setText(away);
        }
    }
    

    运行应用程序后,它会给我一个NullPointException

    无论我是否使用 getActivity() getView() ,它不起作用。

    这背后的概念是什么?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Rene Ferrari    7 年前

    这个 Layout 您的 Fragment 布局 您的 Activity 因此 getActivity().findViewById 将失败。

    onCreateView 充气后 布局 执行以下操作:

    Home = (TextView) v.findViewById(R.id.homename);
    

    一些编码风格提示:使 TextView 的访问权限 private 。命名时以开始 lowercase 和附加 Tv 直到最后所以你知道 private field 是一个 文本框

        2
  •  2
  •   muminers    7 年前

    首先,关于膨胀视图:

    此处的代码:

    View v;
    v = inflater.inflate(R.layout.tab_match_odd, container, false);
    

    “膨胀”视图,这意味着它接受xml文件并只创建所有这些对象。因此,在此之后,v是一个视图,它包含xml中定义的所有其他视图。这就是为什么您可以使用:

    (TextView) v.findViewById(R.id.awayname);
    

    因为这个文本视图是definec内部视图。

    getView()和getActivity()的区别

    另一件事是,您的片段由活动“托管”。它还有自己的视图(通过使用setContentView(…)而膨胀)方法)。通过这一点,您可以使用活动。findViewById(),您将能够在活动的xml文件中找到膨胀的视图(在setContentView()中设置)。 这就是为什么:

    (TextView)v.findViewById(R.id.awayname);
    

    工作,以及

    (TextView) getActivity().findViewById(R.id.awayname);
    

    没有。活动只是没有膨胀包含R.id.awayname的视图。 如您所见:getActivity()只返回“托管”片段的活动,getView()返回从onCreateView()方法返回的视图。

    为什么getView()生成null?

    这是因为在onCreateView()返回语句之前使用了getView()方法。

    怎么办?

    要使其工作,明智的做法是在片段/活动内部创建如下属性:

    公共类TabMatchFragmentOdd扩展片段{ text查看主页,远离;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) {
        View v;
        v = inflater.inflate(R.layout.tab_match_odd, container, false);
        getViews(v);
        return v;
    }
    
    private void getIncomingIntent() {
        (...)
        setContent(HomeName,AwayName);         
    }
    
    private void getViews(View v) {
        Home = (TextView) v.findViewById(R.id.homename);
        Away = (TextView) v.findViewById(R.id.awayname);      
    }
    
    private void setContent(String home, String away) {
        Home.setText(home);
        Away.setText(away);   
    }
    
        3
  •  2
  •   Community CDub    5 年前

    运行应用程序后,出现nullpointexception错误

    无论我使用getActivity()还是getView(),它都不起作用。

    这背后的概念是什么?

    当你打电话的时候 getView() ,您将得到以下结果:

    • 如果 onCreateView() 尚未完成, getView() 退货 null
    • 如果 onCreateView() 已完成, getView() 返回您返回的内容 onCreateView()

    在代码中, setContent() 由调用 getIncomingIntent() ,它由调用 onCreateView() 。这意味着 onCreateView() 尚未完成,所以 getView() 此时将始终返回null。

    对第二段代码所做的最小更改是移动 getIncomingIntent() 从中调用 onCreateView() 并进入 onViewCreated() :

    public class TabMatchFragmentOdd extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return inflater.inflate(R.layout.tab_match_odd, container, false);
        }
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            getIncomingIntent();
        }
    
        private void getIncomingIntent() {
            if (getActivity().getIntent().hasExtra("HomeName") && getActivity().getIntent().hasExtra("AwayName")) {
                String HomeName = getActivity().getIntent().getStringExtra("HomeName").toString();
                String AwayName = getActivity().getIntent().getStringExtra("AwayName").toString();
                setContent(HomeName, AwayName);
            }
            else {
                Toast.makeText(getActivity(), "No:", Toast.LENGTH_SHORT).show();
            }
        }
    
        private void setContent(String home, String away) {
            TextView Home = getView().findViewById(R.id.homename);
            TextView Away = getView().findViewById(R.id.awayname);
            Home.setText(home);
            Away.setText(away);
        }
    }