在片段中使用列表视图

Posted

技术标签:

【中文标题】在片段中使用列表视图【英文标题】:Using list view in fragments 【发布时间】:2015-06-05 20:39:32 【问题描述】:

我有一个抽屉布局片段(在主活动中),它显示一个可扩展列表,当我单击扩展项目的子项目时,会出现一个弹出窗口。这个带有自定义布局的弹出窗口包含文本视图、一个列表视图和 2 个按钮。

我为列表视图提供了 id:android:id="@android:id/list",并从 onCreateView 函数中的 ViewGroup 返回 null,如下所示:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)     
        View rootView = inflater.inflate(R.layout.fragment_settings, null);

并使类扩展 Fragment 而不是 ListFragment

我执行了前 3 个步骤以避免“内容具有 id 属性为 'android.R.id.list' 的视图不是 ListFragment 中的 ListView 类”错误

但我仍然有指向

的 NullPointerException 错误
failListView.setAdapter(adapter);

当点击“故障安全设置”项时

我看到了一些建议,但都没有用,比如 rootView .findViewById?() 不是 getActivity().findViewById() ==> 我已经这样做了。 或在 onCreateView 函数之前声明列表视图。 我真的很生气,我尝试了很多与其他人合作的建议。

尽管如此,我已经尝试将此 sn-p 添加到 onActivityCreated 函数中

  TestFailsafeAdapter adapter = new TestFailsafeAdapter(getActivity().getApplicationContext(),
      R.layout.dialog,R.id.textView1,
      getResources().getStringArray(R.array.failsafe_list));
    failListView.setAdapter(adapter);

任何帮助将不胜感激。

以下是弹出窗口中使用的自定义布局(dialog.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >


    <LinearLayout
        android:id="@+id/headers_container"
        android:layout_
        android:layout_
        android:layout_marginTop="5dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textView1"
            android:layout_
            android:layout_
            android:text="FailSafe"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/textView2"
            android:layout_
            android:layout_
            android:layout_toRightOf="@+id/textView1"
            android:text="On"
            android:textSize="16sp" />

    </LinearLayout>


     <ListView
        android:id="@android:id/list"
        android:layout_
        android:layout_
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/headers_container"
        android:background="#ffeeaa" >
    </ListView> 


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_
        android:layout_
        android:gravity="center"
        android:layout_below="@android:id/list"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/dialogButtonReset"
            android:layout_
            android:layout_
            android:layout_marginRight="5dp"
            android:layout_marginTop="5dp"
            android:text="Reset" />

        <Button
            android:id="@+id/dialogButtonSend"
            android:layout_
            android:layout_
            android:layout_marginRight="5dp"
            android:layout_marginTop="5dp"
            android:text="Send" />
    </LinearLayout>

</RelativeLayout>

以下是具有可绘制布局的可展开列表的片段(SettingsFragment.java):

public class SettingsFragment extends Fragment 


ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;

int position = 0;
ListView failListView = null;


public SettingsFragment() 



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 

    // View rootView = inflater.inflate(R.layout.fragment_settings, container, false);
    View rootView = inflater.inflate(R.layout.fragment_settings, null);     


     failListView = (ListView) rootView.findViewById(android.R.id.list);


  TestFailsafeAdapter adapter = new TestFailsafeAdapter(getActivity().getApplicationContext(),
  R.layout.dialog,R.id.textView1, getResources().getStringArray(R.array.failsafe_list));
  failListView.setAdapter(adapter);

     return rootView;




@Override
public void onActivityCreated(Bundle savedInstanceState) 
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);


    // get the listview
    expListView = (ExpandableListView) getActivity().findViewById(R.id.lvExp);

    // preparing list data
    prepareListData();

    listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild);

    // setting list adapter
    expListView.setAdapter(listAdapter);

    // Listview Group click listener
    expListView.setOnGroupClickListener(new OnGroupClickListener() 


        public boolean onGroupClick(ExpandableListView parent, View v,
                int groupPosition, long id) 
            return false;
        
    );

    // Listview Group expanded listener
    expListView.setOnGroupExpandListener(new OnGroupExpandListener() 

        @Override
        public void onGroupExpand(int groupPosition) 
            Toast.makeText(getActivity(),
                    listDataHeader.get(groupPosition) + " Expanded",
                    Toast.LENGTH_SHORT).show();
        
    );

    // Listview Group collasped listener
    expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() 

        @Override
        public void onGroupCollapse(int groupPosition) 
            Toast.makeText(getActivity(),
                    listDataHeader.get(groupPosition) + " Collapsed",
                    Toast.LENGTH_SHORT).show();

        
    );

    // Listview on child click listener
    expListView.setOnChildClickListener(new OnChildClickListener() 

        @Override
        public boolean onChildClick(ExpandableListView parent, View v,
                final int groupPosition, final int childPosition, long id) 
            // TODO Auto-generated method stub


            if(listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition).equals("USB") )


                FragmentManager manager = getFragmentManager();

                /** Instantiating the DialogFragment class */
                AlertDialogRadio alert = new AlertDialogRadio();

                /** Creating a bundle object to store the selected item's index */
                Bundle b  = new Bundle();

                /** Storing the selected item's index in the bundle object */
                b.putInt("position", position);

                /** Setting the bundle object to the dialog fragment object */
                alert.setArguments(b);

                /** Creating the dialog fragment object, which will in turn open the alert dialog window */
                alert.show(manager, "alert_dialog_radio");

               


            if(listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition).equals("Failsafe Setup") )

                Toast.makeText(getActivity()," Failsafe Setup",Toast.LENGTH_SHORT).show();


                // create a Dialog component
                final Dialog dialog = new Dialog(getActivity());

                //tell the Dialog to use the dialog.xml as it's layout description
                dialog.setContentView(R.layout.dialog);
                dialog.setTitle("Failsafe Setup");


                ListView failListView = (ListView) dialog.findViewById(android.R.id.list);
                Button dialogButtonReset = (Button) dialog.findViewById(R.id.dialogButtonReset);
                Button dialogButtonSend = (Button) dialog.findViewById(R.id.dialogButtonSend);


                dialogButtonReset.setOnClickListener(new OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        Toast.makeText(getActivity()," Failsafe Reset",Toast.LENGTH_SHORT).show();

                    
                );

                dialogButtonSend.setOnClickListener(new OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        Toast.makeText(getActivity()," Failsafe Send",Toast.LENGTH_SHORT).show();
                    
                );

                dialog.show();

            

            return false;
         // end of OnClickChild method
    );






private void prepareListData() 
    listDataHeader = new ArrayList<String>();

    listDataChild = new HashMap<String, List<String>>();  

  // Adding child data
  listDataHeader.add("Connection");
  listDataHeader.add("Mission Limits");
  listDataHeader.add("Compass Calibration");
  listDataHeader.add("Sensor Calibration");
  listDataHeader.add("Failsafe");

 // Adding child data
  List<String> Connection = new ArrayList<String>();
  Connection.add("USB");
  Connection.add("Wi-Fi");


  List<String> MissionLimits = new ArrayList<String>();
  List<String> CompassCalibration = new ArrayList<String>();
  List<String> SensorCalibration = new ArrayList<String>();

  List<String> Failsafe = new ArrayList<String>();
  Failsafe.add("Failsafe Setup");


  listDataChild.put(listDataHeader.get(0), Connection); // Header, Child data
  listDataChild.put(listDataHeader.get(1), MissionLimits); 
  listDataChild.put(listDataHeader.get(2), CompassCalibration); 
  listDataChild.put(listDataHeader.get(3), SensorCalibration); 
  listDataChild.put(listDataHeader.get(4), Failsafe); 


【问题讨论】:

【参考方案1】:

NPE 在这里:

failListView.setAdapter(adapter);

因为ListViewandroid:id/list id 位于dialog.xml 布局中,即Dialog 布局,而不是fragment_settings.xml 中,即SettingsFragment 片段布局。

因此,使用 Dialog 的上下文或对象无法访问 onCreateView 中的 ListView

【讨论】:

那么我如何访问 dialog.xml 中的元素 @ρяσѕρєя K 我在 SettingsFragment.java 类中添加了一行代码,因此代码如下所示: View rootView = inflater.inflate(R.layout.fragment_settings, container, false); rootView2 = inflater.inflate(R.layout.dialog, 容器, false); failListView = (ListView) rootView2.findViewById(android.R.id.list);所以列表视图出现但它是空的,为什么项目没有出现?有什么帮助吗? @jaradat: 从 onCreateView 返回 `rootView2` 它让我 NPE 指向 // 设置列表适配器 expListView.setAdapter(listAdapter); 我需要rootView和rootView2,我怎样才能得到这2个视图??

以上是关于在片段中使用列表视图的主要内容,如果未能解决你的问题,请参考以下文章

SQL 如何查询指定架构中所有表(或视图)的名称

Fragment的ListView项接口定义中的按钮?

无法将查询另存为视图表

如何在相对布局中添加固定标题和滚动视图表行?

访问使用列表框中选择的项目更新子表单

在片段中使用列表视图