如何使用viewpager和fragment将适配器设置为ListView

时间:2016-07-19 01:05:36

标签: android listview android-fragments android-viewpager

我的代码中出现以下错误:

FATAL EXCEPTION: main
                                                                                      Process: com.herprogramacin.hermosaprogramacion, PID: 6541
                                                                                      java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
                                                                                          at com.herprogramacin.hermosaprogramacion.UI.MainActivity$LoadData.onPostExecute(MainActivity.java:215)
                                                                                          at 

com.herprogramacin.hermosaprogramacion.UI.MainActivity$LoadData.onPostExecute(MainActivity.java:195)
                                                                                          at android.os.AsyncTask.finish(AsyncTask.java:651)
                                                                                          at android.os.AsyncTask.access$500(AsyncTask.java:180)
                                                                                          at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                          at android.os.Looper.loop(Looper.java:158)

我使用以下活动代码获取Feed,一旦得到它,我使用函数LoadData将适配器设置为视图。

 public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    public static final String URL_FEED = "http://www.forbes.com/most-popular/feed";

    private ListView listView;

    private FeedAdapter adapter;

    /*
    ViewPager
     */

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private ViewPagerAdapter viewPagerAdapter;

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

        // Obtener la lista
        listView = (ListView)findViewById(R.id.lista);

        ConnectivityManager connMgr = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            VolleySingleton.getInstance(this).addToRequestQueue(
                    new XmlRequest<>(
                            URL_FEED,
                            Rss.class,
                            null,
                            new Response.Listener<Rss>() {
                                @Override
                                public void onResponse(Rss response) {
                                    // Caching
                                    FeedDatabase.getInstance(MainActivity.this).
                                            sincronizarEntradas(response.getChannel().getItems());
                                    // Carga inicial de datos...
                                    new LoadData().execute();
                                }
                            },
                            new Response.ErrorListener() {
                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    Log.d(TAG, "Error Volley: " + error.getMessage());
                                }
                            }
                    )
            );
        } else {
            Log.i(TAG, "La conexi�n a internet no est� disponible");
            adapter= new FeedAdapter(
                    this,
                    FeedDatabase.getInstance(this).obtenerEntradas(),
                    SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
            listView.setAdapter(adapter);
        }


        /*
        Assigning view variables to thier respective view in xml
        by findViewByID method
         */

        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        tabLayout = (TabLayout) findViewById(R.id.tabs);
        viewPager = (ViewPager) findViewById(R.id.viewpager);

        /*
        Creating Adapter and setting that adapter to the viewPager
        setSupportActionBar method takes the toolbar and sets it as
        the default action bar thus making the toolbar work like a normal
        action bar.
         */
        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(viewPagerAdapter);
        setSupportActionBar(toolbar);

        /*
        TabLayout.newTab() method creates a tab view, Now a Tab view is not the view
        which is below the tabs, its the tab itself.
         */

        final TabLayout.Tab noticas = tabLayout.newTab();
        final TabLayout.Tab eventos = tabLayout.newTab();
        final TabLayout.Tab trabajo = tabLayout.newTab();

        /*
        Setting Title text for our tabs respectively
         */

        noticas.setText("Noticias");
        eventos.setText("Eventos");
        trabajo.setText("Trabajo");

        /*
        Adding the tab view to our tablayout at appropriate positions
        As I want home at first position I am passing home and 0 as argument to
        the tablayout and like wise for other tabs as well
         */
        tabLayout.addTab(noticas, 0);
        tabLayout.addTab(eventos, 1);
        tabLayout.addTab(trabajo, 2);

        /*
        TabTextColor sets the color for the title of the tabs, passing a ColorStateList here makes
        tab change colors in different situations such as selected, active, inactive etc

        TabIndicatorColor sets the color for the indiactor below the tabs
         */

//        tabLayout.setTabTextColors(ContextCompat.getColorStateList(this, R.color.tab_selector));
//        tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(this, R.color.indicator));

        /*
        Adding a onPageChangeListener to the viewPager
        1st we add the PageChangeListener and pass a TabLayoutPageChangeListener so that Tabs Selection
        changes when a viewpager page changes.
         */

        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

    }

    @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 LoadData extends AsyncTask<Void, Void, Cursor> {

        @Override
        protected Cursor doInBackground(Void... params) {
            // Carga inicial de registros
            return FeedDatabase.getInstance(MainActivity.this).obtenerEntradas();

        }

        @Override
        protected void onPostExecute(Cursor cursor) {
            super.onPostExecute(cursor);

            // Crear el adaptador
            adapter = new FeedAdapter(
                    MainActivity.this,
                    cursor,
                    SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

            // Relacionar la lista con el adaptador
            listView.setAdapter(adapter);
        }
    }

}

这是我的ViewPager

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        return new TabFragment();    
    }

    @Override
    public int getCount() {
        return 3;           // As there are only 3 Tabs
    }

}

我的Fragment我使用ListFragment实现listview

public class TabFragment extends ListFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.tabs, container, false);
    }
}

在我的活动中将适配器设置为listview时似乎是个问题。我需要在MainActivity中设置它,因为有我的LoadData函数。我应该在片段中使用适配器吗?怎么样?我怎么能实现LoadData呢?

由于

修改

这是我的tabs.xml我在哪里&#34; lista&#34; id

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:id="@+id/lista"
          android:divider="@null"
          android:dividerHeight="0dp"
          android:background="#F1F5F8"
          android:padding="6dp"/>

编辑2:

我想我应该在LoadData中创建寻呼机,并使用&#34; new&#34;发送一个Bundle。函数,然后再将args从viewpager发送到片段。我尝试了但是我在创建捆绑包时遇到错误。

这是我的feedAdapter。

public class FeedAdapter extends CursorAdapter {

/*
Etiqueta de Depuración
 */
private static final String TAG = FeedAdapter.class.getSimpleName();

/**
 * View holder para evitar multiples llamadas de findViewById()
 */
static class ViewHolder {
    TextView titulo;
    TextView descripcion;

    int tituloI;
    int descripcionI;
}

public FeedAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);

}

public View newView(Context context, Cursor cursor, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());

    View view = inflater.inflate(R.layout.item_layout, null, false);

    ViewHolder vh = new ViewHolder();

    // Almacenar referencias
    vh.titulo = (TextView) view.findViewById(R.id.titulo);
    vh.descripcion = (TextView) view.findViewById(R.id.descripcion);

    // Setear indices
    vh.tituloI = cursor.getColumnIndex(ScriptDatabase.ColumnEntradas.TITULO);
    vh.descripcionI = cursor.getColumnIndex(ScriptDatabase.ColumnEntradas.DESCRIPCION);

    view.setTag(vh);

    return view;
}

public void bindView(View view, Context context, Cursor cursor) {

    final ViewHolder vh = (ViewHolder) view.getTag();

    // Setear el texto al titulo
    vh.titulo.setText(cursor.getString(vh.tituloI));

    // Obtener acceso a la descripción y su longitud
    int ln = cursor.getString(vh.descripcionI).length();
    String descripcion = cursor.getString(vh.descripcionI);

    // Acortar descripción a 77 caracteres
     vh.descripcion.setText(descripcion);


}

}

如果我使用adapter = new FeedAdapter(context,cursor,flag),那么&#34; put&#34;我必须使用捆绑包吗? .putserializable,.putString?

// Crear el adaptador
            adapter = new FeedAdapter(
            MainActivity.this,
            cursor,
            SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    Bundle arguments = new Bundle();
    arguments.put(adapter);

    viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), arguments);
    viewPager.setAdapter(viewPagerAdapter);

2 个答案:

答案 0 :(得分:1)

您需要将ListViewtabs.xml移至activity_main.xml(当您致电findViewById时,这就是它所在的位置。然后, 将<ListView android:id="@+id/lista"更改为<ListView android:id="@android:id/list"。可以找到更多信息here

如果xml文件需要单独使用,您可以参考此SO answer

答案 1 :(得分:0)

lv.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.my_layout, R.id.just_an_id, MyList1));

这是我用于片段列表的适配器,它工作得很好