【问题标题】:Cannot get Android tabs with swipable view to correctly pass information from one tab to another and display it correctly无法获取具有可滑动视图的 Android 选项卡以正确地将信息从一个选项卡传递到另一个选项卡并正确显示
【发布时间】:2016-02-05 15:43:51
【问题描述】:

编辑:感谢@ankit aggarwal,我得到了一部分工作,即 TAB 1 没有切换到 TAB 2。在 TAB 2 中不刷新的视图仍然需要帮助。


我正在开发一个使用标签的应用程序。我的应用基于我在互联网上找到的示例here

我拥有的是 TAB 1 中的 ListView。我想要发生的是,当我单击列表中的一个项目时,它会向 TAB 2 发送一个 ID,我想在其中根据传递的数据填充另一个 ListView .我在让它正常工作时遇到问题。

目前,我正在使用它,因此如果我单击 TAB 1 上列表中的一个项目,那么 TAB 2 会获取数据并填充新列表,但是它会添加到 TAB 2 上的视图中,而不是刷新/覆盖/etc.,并且应用程序不会自动切换到新选项卡。这就是我在 TAB 2 中的布局(即接收选项卡):

person.xml

<LinearLayout android:id="@+id/person_information_layout">
    <TextView android:id="@+id/header_row" />
    <LinearLayout>
        <TextView android:id="@+id/column1_row_header" />
        <TextView android:id="@+id/column2_row_header" />
        <TextView android:id="@+id/column3_row_header" />
    </LinearLayout>
    <ListView android:id="@+row_of_data"></ListView>
</LinearLayout>

我正在使用 AdapterView 和数据库游标在接收选项卡 (TAB 2) 中填充此列表。

PersonInformation.java

package myPackage;

public class PersonInformation extends Fragment {

    private View rootView;
    private DatabaseHelper myDBHelper;
    private Cursor informationCursor;
    private SimpleCursorAdapter mySimpleCursorAdapter;

    private TextView personIDDisplay;

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

        rootView = inflater.inflate(R.layout.person, container, false);

        personID = getArguments().getString("personID");

        myDBHelper = new DatabaseHelper(getActivity());

        informationCursor = myDBHelper.getInformationCursor(personID);
        String[] fromColumns = {"firstname", "lastname", "homephone", "homeaddress"};
        int[] toViews = {R.id.firstname_textview, R.id.lastname_textview, R.id.homephone_textview, R.id.homeaddress_textview};
        mySimpleCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.person_information, informationCursor, fromColumns, toViews, 0);

        personIDDisplay = (TextView) rootView.findViewById(R.id.header_row);
        personIDDisplay.setText("Person ID: " + personID);

        ListView myListView = (ListView) rootView.findViewById(R.id.row_of_data);
        myListView.setAdapter(mySimpleCursorAdapter);

        myDBHelper.close();

        return rootView;
    }
}

这是填充的 person_information 布局:

person_information.xml

<LinearLayout>
        <TextView android:id="@+id/column1_data" />
        <TextView android:id="@+id/column2_data" />
        <TextView android:id="@+id/column3_data" />
</LinearLayout>

这是我的发送标签(TAB 1)

Home.java

package myPackage;

public class Home extends Fragment {

    private View rootView;
    private DatabaseHelper myDBHelper;
    private Cursor personCursor;
    private SimpleCursorAdapter mySimpleCursorAdapter;
    private Activity myActivity;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        rootView = inflater.inflate(R.layout.home, container, false);

        myDBHelper = new DatabaseHelper(getActivity());

        personCursor = myDBHelper.getPersonCursor();
        String[] fromColumns = {"personID"};
        int[] toViews = {R.id.person_id_textview};
        mySimpleCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.person_layout, personCursor, fromColumns, toViews, 0);

        ListView myListView = (ListView) rootView.findViewById(R.id.person_row);

        myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Cursor subCursor = (Cursor) mySimpleCursorAdapter.getItem(position);
                String personIDNumber = subCursor.getString(subCursor.getColumnIndex("personID"));

                PersonInformation personInformation = new PersonInformation();
                Bundle myBundle = new Bundle();
                myBundle.putString("personID", personIDNumber);
                personInformation.setArguments(myBundle);
                getFragmentManager().beginTransaction().replace(R.id.person_information_layout, personInformation).commit();
            }
        });

        myListView.setAdapter(mySimpleCursorAdapter);

        myDBHelper.close();

        return rootView;
    }
}

如您所见,我有一个布局,其中包含顶部信息行,然后是列标题行,然后是数据行。我想要的是这样的:

Top Information Row
Column Headers
data row 1
data row 2
...
data row n

目前,当我单击 TAB 1 中的人时,TAB 2 确实从 TAB 1 获取数据并正确填充了一个新列表,但是它在已经存在的顶级信息行和列标题下绘制它,所以我有图层:

Top Information Row
Column Headers
Top Information Row
Column Headers
data row 1
data row 2
...
data row n

此外,当我单击 TAB 1 中的一行时,该选项卡不会自动从 TAB 1 切换到 TAB 2。

而不是发送选项卡中的这一行(TAB 1)

getFragmentManager().beginTransaction().add(R.id.person_information_layout, personInformation).commit();

我把它改成了这一行:

getFragmentManager().beginTransaction().add(R.id.row_of_data, personInformation).commit();

但我得到了错误:

"addView(View) not supported in AdapterView"

据我了解,我无法将视图添加到 ListView,因此我将其更改回 ListView 的父级,但随后我得到了重复的视图。

我一直想改变我的接收标签(TAB 2)中的行

ListView myListView = (ListView) rootView.findViewById(R.id.row_of_data);

到这里

LinearLayout myLinearLayout = (LinearLayout) rootView.findViewById(R.id.person_information_layout);

但是光标适配器无法使用。

我需要做什么才能让它工作?

【问题讨论】:

    标签: android listview android-fragments android-tabs


    【解决方案1】:

    (1)

    目前,当我点击 TAB 1 中的人时,TAB 2 确实会获取数据 从 TAB 1 并正确填充一个新列表,但是它会绘制它 在已经存在的顶部信息行和列标题下,所以 我有图层:

    发生这种情况是因为此语句不是切换到 tab2,而是在您的活动框架顶部添加一个新片段。

    getFragmentManager().beginTransaction().add(R.id.person_information_layout, personInformation).commit();

    (2)

    此外,当我打开标签页时,标签不会自动从标签页 1 切换到标签页 2 点击 TAB 1 中的一行。

    您在此选项卡实现中使用了 viewpager。所以要更改为 tab2 你可以做

    viewPager.setCurrentItem(2);
    

    注意:这里缺少的是视图寻呼机自动将上一页和下一页加载到特定页面。所以当你在 tab1 中时,tab2 已经被加载了。因此,当您单击列表项时,您的 tab2 不会刷新,因为它已经加载了。

    【讨论】:

    • 我试过 beginTransaction.replace() 但它也没有取代它。
    • 这是因为您在另一个视图之上添加了一个新视图。虽然这不是实现您想要的目标的正确方法,但您可以使用 replace 而不是 add()。并确保将布局宽度和高度设置为匹配父级,如果仍然存在,则为父级布局设置背景
    • 就像我说的,我尝试了“替换”,但结果是一样的。
    • 你必须改变你的实现。在 fragment2 中创建一个方法,每次单击列表时调用该方法,并在该方法中传递相关信息。并在该方法中更新您的 api
    • 我不确定我是否听懂了你的意思。
    【解决方案2】:

    我解决类似问题的方法是创建从活动到片段的回调方法以及从片段到活动的回调方法。当我点击片段1列表中的一行时,我将信息保存在该片段的参数中,并调用活动的回调函数。在该函数中,我检索传递的信息并将其加载到 fragment2 的参数并调用 fragment2 的回调函数。在那里我检索传递的信息并更新fragment2的列表。然后我在activity中调用tabLayout.getTabAt(newPosition),重新显示fragment2的页面。您还必须确保,由于片段的视图在页面之间的一次移动中被破坏,因此检查片段是否仍然填充了列表,如果没有,则恢复列表中的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 2016-04-30
      • 2016-10-22
      • 1970-01-01
      • 2014-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多