Реализация SwipeView, SwipeRefreshlayout и Navigation Drawer в одном действии

как следует из названия, я пытаюсь реализовать все эти функции одновременно. Первоначально у меня была полностью функционирующая боковая навигация с SwipeRefreshLayout, которая содержит представление списка (с использованием пользовательского адаптера списка). Затем я добавил ViewPager внутри SwipeRefreshLayout, и все в основном работает… за исключением того, что когда я прокручиваю, список иногда не появляется на новых «вкладках». В большинстве случаев я вижу первую страницу и список, пролистываю вправо, ничего, пролистываю вправо, ничего, прокручиваю влево, просматриваю список, прокручиваю в начало, ничего.

Я должен добавить, что все полностью динамично, элементы навигации получены с моего сервера (что также является количеством страниц), и каждая страница имеет собственный адаптер списка с различными элементами списка. Вся эта динамическая информация, по-видимому, правильно принимается и адаптируется для каждого пролистывания страницы и т. д.

Теперь о коде!

Макет ящика со встроенным swiperefreshlayout и просмотром пейджера. "ящик.xml"

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"> 

    <android.support.v4.widget.SwipeRefreshLayout       xmlns:android="http://schemas.android.com/apk/res/android"    
   android:id="@+id/swipe_container"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical" >
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</android.support.v4.widget.SwipeRefreshLayout>
    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
     <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        />


    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         The drawer is given a fixed width in dp and extends the full height of
         the container. A solid background is used for contrast
         with the content view. -->
     <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/grey_lighter"
        android:dividerHeight="1dp"
        android:background="#FFFFFF"/>
</android.support.v4.widget.DrawerLayout>

Listview, который содержит настраиваемые элементы списка, созданные динамически в действии «dashboard.xml»:

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


    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/LV_dashboard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_alignRight="@+id/textView1"
        android:layout_below="@+id/textView1" >

    </ListView>

Теперь для активности фрагмента:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this.getApplicationContext();
        navItems = new ArrayList<String>();
        this.setContentView(R.layout.drawer); 
        mMerchantIds = Session.get().getMerchID(); //array retrieved from cache used for api

        mCustomerPagerAdapter = new CustomerPagerAdapter(getSupportFragmentManager());


        // Set up the ViewPager, attaching the adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mCustomerPagerAdapter);

        mTitle = mDrawerTitle = getTitle();

        mNavTitles = getResources().getStringArray(R.array.nav_array); //I realize this isn't dynamic, I haven't gotten around to that just yet.

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);
        connection = new WiselyRequest();

        // set a custom shadow that overlays the main content when the drawer opens
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        // set up the drawer's list view with items and click listener
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.nav_item, mNavTitles));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        // enable ActionBar app icon to behave as action to toggle nav drawer
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        // ActionBarDrawerToggle ties together the the proper interactions
        // between the sliding drawer and the action bar app icon
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
                ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            selectItem(0);
        }    
    }

Это разветвляется на две части, мы начнем с ящика:

private class DrawerItemClickListener implements ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectItem(position);
            }
        }

        private void selectItem(int position) {
            // update the main content by replacing fragments (this is not what the pager does)
            Fragment fragment = null;

            fragment = new CustomerFragment();
            Bundle args = new Bundle();
            args.putString(KEY_MERCHANT_ID, (mMerchantIds.get(position)));
            fragment.setArguments(args);
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();


            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);

            setTitle(mNavTitles[position]);



            mDrawerLayout.closeDrawer(mDrawerList);

        }

Вот пейджер просмотра:

public class CustomerPagerAdapter extends FragmentPagerAdapter {

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

            @Override
            public Fragment getItem(int i) {
                Fragment fragment = new CustomerFragment();
                Bundle args = new Bundle();
                Log.d("Wisely", "merchants: "+mMerchantIds.get(i));
                args.putString(KEY_MERCHANT_ID, (mMerchantIds.get(i))); // Our object is just an integer :-P
                fragment.setArguments(args);
                return fragment;
            }

            @Override
            public int getCount() {
                // For this contrived example, we have a 100-object collection.
                return mMerchantIds.size(); //equal to the number of merchantss (that many customer objects) 
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return "OBJECT " + (position + 1);
            }
        }

Вот фрагмент клиента, который используют и ящик, и пейджер, и где обрабатывается обновление:

 public class CustomerFragment extends Fragment implements OnRefreshListener {
                private View rootView;
                SwipeRefreshLayout swipeLayout; 
                public CustomerFragment() {

                }

                @Override
                public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                    Bundle args = getArguments();
                    String merchantID = args.getString(KEY_MERCHANT_ID);
                    if(connection.checkConnectivity(getApplicationContext())){
                        getRecentCustomers(API.getRecentCustomers()+"?merchant_id="+merchantID); //api call works totally fine, and correctly sets up the adapter
                    }
                    else
                        Toast.makeText(DashboardActivity.this, "Need to be connected to the internet!", 4000).show();
                    rootView = inflater.inflate(R.layout.dashboard, container, false);//inflates the dashboard
                    swipeLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_container);
                    swipeLayout.setOnRefreshListener(this);
                     swipeLayout.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light);
                    registerClickCallback(rootView);

                    return rootView;    
                }

                @Override
                public void onRefresh() {
                    if(connection.checkConnectivity(getApplicationContext()))
                        reloadActivity(); //literally turns the activity on and off without animation
                    else
                        Toast.makeText(DashboardActivity.this, "Need to be connected to the internet!", 4000).show();
                }

Я считаю, что проблема возникает в моих макетах, а не в адаптере списка или фрагменте клиента, которые, кажется, работают нормально (каждый раз, когда я перехожу на новую страницу, вызывается API, и правильные данные помещаются в представление списка. Я просто могу не вижу. Также я понимаю, что навигационный элемент не является динамическим, но моя большая проблема на данный момент заключается в возможности прокручивать несколько списков на страницах. Когда я изменяю свой клиентский фрагмент, чтобы раздуть простое текстовое представление с числом в нем , кажется, работает нормально, за исключением того, что первая страница никогда не исчезает, другие страницы просто складываются поверх нее (я думаю, что это связано с макетом фрейма в ящике, но его удаление нарушает код, потому что мой ящик ворчания полагается на него ). Какие-либо предложения?


person Arj    schedule 02.10.2014    source источник


Ответы (1)


Я думаю, вам придется создавать свои собственные классы, расширяющие DrawerLayout или ViewPager. Внутри ваших классов вы должны переопределить методы:

onInterceptTouchEvent() - здесь вы оцениваете TouchEvent и возвращаете true, если вы его перехватываете (не переходите к дочернему представлению)

Вы должны настроить условия перехвата в зависимости от того, чего вы пытаетесь достичь.

Руководство находится здесь: http://developer.android.com/training/gestures/viewgroup.html

person JanKnotek    schedule 02.10.2014