android - 如何使用 viewpager 和 fragment 将适配器设置为我的 ListView

标签 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)

我在我的 Activity 中使用以下代码获取提要,获取提要后,我使用函数 LoadData 将适配器设置为 View 。

 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
    }

}

还有我使用 ListFragment 实现 ListView 的 Fragment

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

当我在我的 Activity 中将适配器设置为 ListView 时,这似乎是一个问题。我需要在我的 MainActivity 中设置它,因为有我的 LoadData 函数。我应该在 fragment 中使用适配器吗?如何?那么我该如何实现 LoadData?

谢谢

编辑:

这是我的 tabs.xml,我在其中使用“lista”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 中创建寻呼机并发送一个带有"new"函数的 Bundle,然后再次将 args 从 viewpager 发送到 fragment 。我试过了,但在创建 bundle 时遇到错误。

这是我的 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),我必须将哪种“放置”与 bundle 一起使用? .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);

最佳答案

您需要移动 ListView来自 tabs.xmlactivity_main.xml (当你调用 findViewById 时它正在看的地方。然后, 更改 <ListView android:id="@+id/lista"<ListView android:id="@android:id/list" .可以找到更多信息here .

如果xml文件需要自己,可以引用这个SO answer .

关于android - 如何使用 viewpager 和 fragment 将适配器设置为我的 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38448072/

相关文章:

android - 主屏幕快捷方式的应用程序标题不会随手机语言更改而更改

android - fragment 中的 ListView 使用 ArrayAdapter 未设置

android - 当我单击第二个 fragment android 中的按钮时,查看寻呼机跳到不规则位置?

来自 fragment 的android PopupWindow

android - 如何将 ListView 行中的 TextView 中的值放入 fragment

android - Firebase UI RecyclerView onClick

android - 软件包安装程序对话框可以关闭吗?

安卓用户界面设计 : Interactive ListView Elements

android - 应用程序无法安装 Android 9 (Pie)

java - 打开 Activity 并根据 ListView 选择进行填充