java 如何使用 ListViews 创建标签式活动 - Android

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40259159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:04:39  来源:igfitidea点击:

How to create a Tabbed Activity with ListViews - Android

javaandroidxmllistview

提问by spaceengineer

First of all, I'm a beginner in Android programming. What I'm trying to do is to program three Tabs with each a ListView inside (you know it from e.g. WhatsApp). Android Studio makes it easy to automatically create a Tabbed Activity. So the question is: how can I implement a ListView for each Tab? Actually there is a nice tutorial on http://www.androidhive.info/2012/05/android-combining-tab-layout-and-list-view/which uses TabActivity. However this method is deprecated and Fragments should be used instead. I have extended main_fragment.xml (which was created by Android Studio) with a ListView. But what is the correct way to set the corresponding list adapters and especially where to set them? Setting them like ListView list_all = (ListView) findViewById(R.id.listViewAll)in onCreate()does not work because of a null object reference error. Also I didn't find out how to use the rootViewwhich is returned by onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)So how can I solve this problem?

首先,我是Android编程的初学者。我想要做的是编写三个标签,每个标签里面都有一个 ListView(你从例如 WhatsApp 知道的)。Android Studio 可以轻松自动创建选项卡式活动。所以问题是:如何为每个 Tab 实现一个 ListView?实际上,http://www.androidhive.info/2012/05/android-combining-tab-layout-and-list-view/上有一个使用 TabActivity的不错的教程。但是,此方法已弃用,应改用 Fragments。我使用 ListView 扩展了 main_fragment.xml(由 Android Studio 创建)。但是设置相应列表适配器的正确方法是什么,尤其是在哪里设置它们?将它们设置ListView list_all = (ListView) findViewById(R.id.listViewAll)onCreate()由于空对象引用错误而不起作用。另外我没有找到如何使用rootView返回的onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)那个 那么我该如何解决这个问题呢?

main_fragment.xml:

main_fragment.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:background="@color/colorAccent"
    android:paddingTop="@dimen/activity_vertical_margin">

    <ListView
        android:id="@+id/listViewAll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>

</RelativeLayout>

main.xml:

主文件:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="@color/white"

    tools:context="de.url.members">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/appbar_padding_top"
        android:background="@color/bg_login_dark"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/bg_login_dark"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay">

        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMaxWidth="0dp"
            app:tabGravity="fill"
            app:tabMode="fixed"
            android:fillViewport="false" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

main.java:

主.java:

public class main extends AppCompatActivity {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;


    // The {@link ViewPager} that will host the section contents.
    private ViewPager mViewPager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            // action here
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_members, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.logout) {
            //action here
        }

        return super.onOptionsItemSelected(item);
    }


    /**
     * A placeholder fragment containing a simple view.
     */

    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        public PlaceholderFragment() {
        }

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

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

            int sectionNumber = getArguments().getInt(ARG_SECTION_NUMBER);//INDEX of selected TAB
            View rootView;

            if (sectionNumber == 1){
                rootView = inflater.inflate(R.layout.main_fragment, container, false);
            }else if (sectionNumber == 2){
                rootView = inflater.inflate(R.layout.main_fragment, container, false);                 
            }else if (sectionNumber == 3){
                rootView = inflater.inflate(R.layout.main_fragment, container, false);                  
            }else{
                rootView = inflater.inflate(R.layout.main_fragment, container, false);

            }

            return rootView;
        }
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            return PlaceholderFragment.newInstance(position + 1);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return getResources().getString(R.string.title_section1);
                case 1:
                    return getResources().getString(R.string.title_section2);
                case 2:
                    return getResources().getString(R.string.title_section3);
            }
            return null;
        }
    }
}

采纳答案by Aditya Vyas-Lakhan

If you want to use Listing with tablayout and viewpager try this way it will work for you

如果您想将 Listing 与 tablayout 和 viewpager 一起使用,请尝试这种方式,它对您有用

public class MainActivity extends AppCompatActivity {
    private static Toolbar toolbar;
    private static ViewPager viewPager;
    private static TabLayout tabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        setupViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tabLayout);
        tabLayout.setupWithViewPager(viewPager);//setting tab over viewpager

        //Implementing tab selected listener over tablayout
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());//setting current selected item over viewpager
                switch (tab.getPosition()) {
                    case 0:
                        Log.e("TAG","TAB1");
                        break;
                    case 1:
                        Log.e("TAG","TAB2");
                        break;
                    case 2:
                        Log.e("TAG","TAB3");
                        break;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });
    }


    //Setting View Pager
    private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFrag(new DummyFragment("ANDROID"), "ANDROID");
        adapter.addFrag(new DummyFragment("iOS"), "iOS");
        adapter.addFrag(new DummyFragment("WINDOWS"), "WINDOWS");
        viewPager.setAdapter(adapter);
    }


    //View Pager fragments setting adapter class
    class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();//fragment arraylist
        private final List<String> mFragmentTitleList = new ArrayList<>();//title arraylist

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }


        //adding fragments and title method
        public void addFrag(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }
}

For more see android-material-design-tabs-using-tablayout

有关更多信息,请参阅android-material-design-tabs-using-tablayout

OR

或者

Check this http://www.tutorialsbuzz.com/2015/10/Android-Sliding-TabLayout-ListView-WhatsApp.html

检查这个http://www.tutorialsbuzz.com/2015/10/Android-Sliding-TabLayout-ListView-WhatsApp.html

And check this https://github.com/codepath/android_guides/wiki/Handling-Scrolls-with-CoordinatorLayout

并检查这个https://github.com/codepath/android_guides/wiki/Handling-Scrolls-with-CoordinatorLayout

OUTPUT

输出

enter image description here

enter image description here

回答by spaceengineer

I have solved it now by simply editing the getItem()method of public class SectionsPagerAdapterin main.java. Just return a default ListFragment instead of the PlaceholderFragment. Interesting note: Returning the same ListFragment object for all tabs leads to an error.

我现在通过简单地编辑main.java中的getItem()方法解决了它public class SectionsPagerAdapter。只需返回一个默认的 ListFragment 而不是 PlaceholderFragment。有趣的注意事项:为所有选项卡返回相同的 ListFragment 对象会导致错误。

main.java:

主.java:

public class MainActivity extends AppCompatActivity {

    private ArrayAdapter<String> adapter;

    private ListFragment contacts1 = new ListFragment();
    private ListFragment contacts2 = new ListFragment();
    private ListFragment contacts3 = new ListFragment();

    List<String> words = new ArrayList<String>();

    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        words.add("Hello");
        words.add("World");
        words.add("!");
        adapter = new ArrayAdapter<String>(this,R.layout.item,words);
        contacts1.setListAdapter(adapter);
        contacts2.setListAdapter(adapter);
        contacts3.setListAdapter(adapter);


        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Update List", Snackbar.LENGTH_LONG).setAction("Action", null).show();
                words.add("New Item");
                adapter.notifyDataSetInvalidated();
            }
        });

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public ListFragment getItem(int position) {

            if (position == 0){
                return contacts1;
            }else if (position == 1){
                return contacts2;
            }else{
                return contacts3;
            }


        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return "SECTION 1";
                case 1:
                    return "SECTION 2";
                case 2:
                    return "SECTION 3";
            }
            return null;
        }
    }
}

回答by Marc

I will explain what you have to do to put a ListView on one of the fragments. (Sorry if I write a bad English)

我将解释您必须做什么才能将 ListView 放在其中一个片段上。(对不起,如果我写的英语不好)

You should put your listView view on the xml witch is displayed by one of your fragments. In the code that you have post the layout witch fragment displays is R.layout.main_fragment

您应该将您的 listView 视图放在由您的片段之一显示的 xml 女巫上。在您发布布局女巫片段显示的代码中是 R.layout.main_fragment

Then on the fragment you have to declare your ListView:

然后在片段上你必须声明你的 ListView:

ListView list_all = (ListView) rootView.findViewById(R.id.listViewAll);

ListView list_all = (ListView) rootView.findViewById(R.id.listViewAll);

You have to create a ListView adapter, an object class and some other files, you can use the tutorial witch you have post.

您必须创建一个 ListView 适配器、一个对象类和一些其他文件,您可以使用您发布的教程女巫。

Link

关联

Then write your code to set an Adapter to this ListView after the rootView is assigned on the fragment:

然后编写代码以在片段上分配 rootView 后将 Adapter 设置为此 ListView:

if (sectionNumber == 1){
        rootView = inflater.inflate(R.layout.main_fragment, container, false);
        }else if (sectionNumber == 2){
            rootView = inflater.inflate(R.layout.main_fragment, container, false);                 
        }else if (sectionNumber == 3){
            rootView = inflater.inflate(R.layout.main_fragment, container, false);                  
        }else{
            rootView = inflater.inflate(R.layout.main_fragment, container, false);
}

ArrayList<Object> arrayListOfObjects = new ArrayList<>();
arrayListOfObjects.add(new Object(...));
MyAdapter adapter = new MyAdapter(arrayListOfObjects);
list_all.setListAdapter(adapter);