Вкладки панели действий — исключение нулевого указателя

#java #android #android-fragments #android-fragmentactivity #android-tabs

#java #Android #android-фрагменты #android-fragmentactivity #android-вкладки

Вопрос:

Я пытаюсь реализовать вкладки actionbar, которые являются фрагментами, используя этот учебник, но я продолжаю получать эту ошибку:

LogCat:

 06-16 17:00:46.778: E/AndroidRuntime(25789): FATAL EXCEPTION: main
06-16 17:00:46.778: E/AndroidRuntime(25789): java.lang.NullPointerException
06-16 17:00:46.778: E/AndroidRuntime(25789):    at com.myapp.Main.initWidgets(Main.java:115)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at com.myapp.Main.onCreateView(Main.java:52)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:938)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:478)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.os.Handler.handleCallback(Handler.java:605)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.os.Handler.dispatchMessage(Handler.java:92)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.os.Looper.loop(Looper.java:137)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at android.app.ActivityThread.main(ActivityThread.java:4441)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at java.lang.reflect.Method.invokeNative(Native Method)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at java.lang.reflect.Method.invoke(Method.java:511)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-16 17:00:46.778: E/AndroidRuntime(25789):    at dalvik.system.NativeStart.main(Native Method)
  

Я новичок в фрагментах, так что кто-нибудь может помочь мне решить эту проблему? Вот мой код фрагмента, который вызывает ошибку:

 public class Main extends Fragment {

    private SharedPreferences prefs;
    private Latest latest;
    private ArrayList<ActivityItems> activities;
    private MainAdapter adapter;
    private ListView list;

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

        View rootView = inflater.inflate(R.layout.main_activity, container,
                false);
        prefs = getActivity().getSharedPreferences(
                getActivity().getPackageName(), getActivity().MODE_PRIVATE);
        Log.v("--", prefs.getString(Constants.TOKEN, "")   " TNK");
        initWidgets();
        return rootView;
    }

    private void initWidgets() {
        activities = new ArrayList<ActivityItems>();
        list = (ListView) getActivity().findViewById(R.id.main_activity_list);

        // initActionBar();
        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                getActivityData();
                try {
                    JSONObject jObj = new JSONObject(getLatest());

                    for (int i = 0; i < jObj.getJSONArray("items").length(); i  ) {
                        JSONObject j = jObj.getJSONArray("items")
                                .getJSONObject(i);

                        JSONObject userJson = j.getJSONObject("user");
                        JSONObject me = userJson.getJSONObject("me");
                        boolean following = me.getBoolean("following");

                        User user = new User(userJson.getInt("id"),
                                userJson.getString("username"),
                                userJson.getString("name"),
                                userJson.getString("location"),
                                userJson.getString("avatar_url"), following);

                        JSONObject meLiked = j.getJSONObject("me");

                        activities.add(new ActivityItems(j.getInt("id"), j
                                .getInt("views_count"),
                                j.getInt("likes_count"), j
                                        .getInt("comments_count"), j
                                        .getString("title"), j
                                        .getString("image_url"), j
                                        .getString("image_url_large"), j
                                        .getString("image_url_small"), j
                                        .getString("created_at"), meLiked
                                        .getBoolean("liked"), user));
                    }

                    latest = new Latest(jObj.getInt("page_count"),
                            jObj.getInt("total_count"), activities);

                } catch (JSONException e) {
                    e.printStackTrace();
                }

                return null;
            }

            protected void onPostExecute(Void result) {

                Log.v("--", activities.size()   " activities");
                adapter = new MainAdapter(getActivity(), activities);
                list.setAdapter(adapter);
            };
        }.execute();

        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                try {
                    Intent intent = new Intent(getActivity(), ItemDetails.class);
                    intent.putExtra(Constants.ITEM_DETAILS,
                            activities.get(position));
                    startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

    }

    private String getLatest() {
        HttpClient httpclient = new DefaultHttpClient();
        String result = null;
        // Prepare a request object
        HttpGet httpget = new HttpGet(
                "http://api.staging.server.com/v1/shots/latest?access_token="
                          prefs.getString(Constants.TOKEN, ""));

        // Execute the request
        HttpResponse response;
        try {
            response = httpclient.execute(httpget);
            // Examine the response status
            Log.i("Praeda", response.getStatusLine().toString());

            // Get hold of the response entity
            HttpEntity entity = response.getEntity();
            // If the response does not enclose an entity, there is no need
            // to worry about connection release

            if (entity != null) {

                // A Simple JSON Response Read
                InputStream instream = entity.getContent();
                result = convertStreamToString(instream);
                // now you have the string representation of the HTML request
                instream.close();
            }

        } catch (Exception e) {
        }
        return resu<
    }

    private String getActivityData() {
        HttpClient httpclient = new DefaultHttpClient();
        String result = null;
        // Prepare a request object
        HttpGet httpget = new HttpGet(
                "http://api.staging.server.com/v1/session/activity?access_token="
                          prefs.getString(Constants.TOKEN, ""));

        // Execute the request
        HttpResponse response;
        try {
            response = httpclient.execute(httpget);
            // Examine the response status
            Log.i("Praeda", response.getStatusLine().toString());

            // Get hold of the response entity
            HttpEntity entity = response.getEntity();
            // If the response does not enclose an entity, there is no need
            // to worry about connection release

            if (entity != null) {

                // A Simple JSON Response Read
                InputStream instream = entity.getContent();
                result = convertStreamToString(instream);
                // now you have the string representation of the HTML request
                instream.close();
            }

        } catch (Exception e) {
        }
        return resu<
    }

    public static String convertStreamToString(InputStream is) {
        /*
         * To convert the InputStream to String we use the
         * BufferedReader.readLine() method. We iterate until the BufferedReader
         * return null which means there's no more data to read. Each line will
         * appended to a StringBuilder and returned as String.
         */
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line   "n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

}
  

И вот фрагмент действия, который содержит фрагменты вкладки:

 public class ActivityExample extends FragmentActivity implements
        ActionBar.TabListener {

    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Following", "Popular", "Latest" };

    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabbed_activity);

        // Initilization
        initActionBar();
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());

        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }


        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

    private void initActionBar() {
        // title bar init
        final ViewGroup actionBarLayout = (ViewGroup) getLayoutInflater()
                .inflate(R.layout.activity_actionbar, null);
        // Set up your ActionBar
        final ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setCustomView(actionBarLayout);
        Typeface mTypeface = Typeface.createFromAsset(getAssets(),
                "rockwell.ttf");
        TextView title = (TextView) findViewById(R.id.activity_action_title);

        // ImageButton back = (ImageButton) findViewById(R.id.signup_back);
        // Button signUp = (Button) findViewById(R.id.signup_signup);
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayHomeAsUpEnabled(false);
        getActionBar().setDisplayHomeAsUpEnabled(false);
        title.setText("Home");
        title.setGravity(Gravity.CENTER);
        title.setTypeface(mTypeface);
        title.setTextSize(20);

    }

}
  

И вот мой tabAdapter

 public class TabsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new FollowingTab();
        case 1:
            // Games fragment activity
            return new PopularTab();
        case 2:
            // Movies fragment activity
            return new Main();
        }

        return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }

}
  

Ответ №1:

Вероятно, ваш listview находится внутри макета фрагмента, и вы вызываете:

 list = (ListView) getActivity().findViewById(R.id.main_activity_list);
  

Вы должны передать rootView в initWidgets(), вызвав initWidgets(rootView) и в initWidgets поместить:

 private void initWidgets(View rootView) {
    activities = new ArrayList<ActivityItems>();
    list = (ListView) rootView.findViewById(R.id.main_activity_list);

    ...

}
  

Комментарии:

1. Да, Зоран, большое спасибо, это решение. Fala ti mnogu 🙂

2. Добро пожаловать! Nema na cemu :). Ознаки да я решен 😉

3. Я отмечу, что он должен быть активным в течение нескольких минут, прежде чем я его приму. Теперь, когда я нажимаю на элемент в ListView, я получаю это из logCat:pastebin.com/D1XGGmqb . Это происходит, когда я нажимаю на элемент в списке и пытаюсь начать новое действие, выполнив: list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getActivity(), ItemDetails.class); intent.putExtra(Constants.ITEM_DETAILS, activities.get(position)); getActivity().startActivity(intent); } }); Есть идеи?

4. Isto tako reci mi dali radis i dali imas posao?

5. Попробуйте поместить весь list.setOnItemClickListener в onPostExecute после list.setAdapter(адаптер);