Android FragmentTabHost:NullPointerException:Drawable.setState(int[])在空对象引用上
作为一名Android程序员新手,我一直在努力学习如何设置一个简单的选项卡式UI。因为我认为这是当今的最佳实践,所以我决定将我的布局基于FragmentTabHost,因为我正在处理片段,我的主要活动也基于FragmentActivity(通过扩展AppCompativeActivity) 我的测试应用程序的结构如下:我有一个带有线性布局的主活动,其中包含一个片段,用于显示另一个布局文件中定义的不同选项卡。我扩展了Fragment以创建一个TabsFragment类,该类基于不同的布局使用FragmentTabHost实现这个选项卡UI。我希望有两个选项卡:一个显示名称列表,另一个仅显示文本(名称是通过我已经彻底测试过的类生成的) 我使用的文件如下所示: MainActivity.javaAndroid FragmentTabHost:NullPointerException:Drawable.setState(int[])在空对象引用上,android,Android,作为一名Android程序员新手,我一直在努力学习如何设置一个简单的选项卡式UI。因为我认为这是当今的最佳实践,所以我决定将我的布局基于FragmentTabHost,因为我正在处理片段,我的主要活动也基于FragmentActivity(通过扩展AppCompativeActivity) 我的测试应用程序的结构如下:我有一个带有线性布局的主活动,其中包含一个片段,用于显示另一个布局文件中定义的不同选项卡。我扩展了Fragment以创建一个TabsFragment类,该类基于不同的布局使用Fra
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
private Toolbar appToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d ( TAG, "onCreate: setting content view" );
setContentView ( R.layout.activity_main );
appToolbar = ( Toolbar ) findViewById ( R.id.toolbar );
setSupportActionBar ( appToolbar );
Log.d ( TAG, "onCreate finished")
}
@Override
public boolean onCreateOptionsMenu ( Menu menu ) {
appToolbar.inflateMenu ( R.menu.menu_actions );
return ( true );
}
}
TabsFragment.java
import android.app.ListFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.FragmentTabHost;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.TabHost;
/**
* Created by Joshua on 12/12/2016.
*/
public class TabsFragment extends Fragment implements TabHost.OnTabChangeListener {
private String TAG = "TabsFragment";
/* Fixed tags for the different tabs */
public static final String OVERVIEW_TAB_TAG = "TAB_OVERVIEW";
public static final String SEARCH_TAB_TAG = "TAB_SEARCH";
/* Objects necessary to build activity views
*/
private LayoutInflater mInflater; // Used for building View objects in memory from our XML-resources
/* The views and other fragments our fragment will contain and helper variables for accessing them
*/
private View mRoot; // A reference to the root vie of our fragment
private FragmentTabHost mFragmentTabHost; // A reference to the tab host ( tab controlling ) view of our fragment
private String labelOverviewTab = "Overview";
private String labelSearchTab = "Searhc";
private CustomListFragment overviewTabFragment;
private TextFragment searchTabFragment;
/* Other fragment bookkeeping variables
*/
private String mCurrentTab; // Stores the tag of the currently visible tag
/* Data and adapters for our views */
private Persons personsInfo;
private ListAdapter namesListAdapter;
/* This method will get executed when the system wants to recreate our view
i.e. when the user returns or enters our tabs interface
It will return a reference to the root node of the views tree
*/
@Override
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
super.onCreateView ( inflater, container, savedInstanceState );
Log.d ( TAG, "onCreateView: starting ..." );
/* Create all the view objects we need in memory and make sure the references to them in our class are correct
*/
mRoot = inflater.inflate ( R.layout.tabs_fragment, container, false );
mFragmentTabHost = ( FragmentTabHost ) mRoot.findViewById ( android.R.id.tabhost );
Log.d ( TAG, "onCreateView: layouts inflated ... Attempting FragmentTabHost setup: ..." );
mFragmentTabHost.setup ( getContext ( ), getChildFragmentManager ( ), android.R.id.tabcontent );
Log.d ( TAG, "onCreateView: setup finished without errors ..." );
/* Initialize the tab host and make sure it's aware of all the tabs it has to manage
*/
TabHost.TabSpec overviewTabSpec = mFragmentTabHost.newTabSpec ( OVERVIEW_TAB_TAG );
TabHost.TabSpec searchTabSpec = mFragmentTabHost.newTabSpec ( SEARCH_TAB_TAG );
overviewTabSpec = overviewTabSpec.setContent ( R.id.overviewTab ).setIndicator ( labelOverviewTab );
searchTabSpec = searchTabSpec.setContent ( R.id.searchTab ).setIndicator ( labelSearchTab );
Log.d ( TAG, "onCreateView: created tab specs with TAG's " + overviewTabSpec.getTag ( ) + " & " + searchTabSpec.getTag ( ) );
Persons personsInfo = new Persons ( );
personsInfo.addPerson ( "Stanley", "Kubrick", 21 );
personsInfo.addPerson ( "Steven", "Spielberg", 20 );
personsInfo.addPerson ( "Quentin", "Tarantino", 18 );
personsInfo.addPerson ( "Joel", "Coen", 24 );
personsInfo.addPerson ( "Ethan", "Coen", 26 );
Log.d ( TAG, "onCreateView: initialized data" );
overviewTabFragment = new CustomListFragment ( );
overviewTabFragment.setFragmentContext ( getContext( ) );
overviewTabFragment.setDataSource ( personsInfo );
searchTabFragment = new TextFragment ( );
searchTabFragment.setUniqueTag ( "Search" );
searchTabFragment.setTabText ( "Here you will be able to SEARCH" );
Log.d ( TAG, "onCreateView: created fragments" );
mCurrentTab = OVERVIEW_TAB_TAG;
Log.d ( TAG, "onCreateView: set current tab variable to " + OVERVIEW_TAB_TAG );
getFragmentManager ( ).beginTransaction ( ).add ( overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
mFragmentTabHost.addTab ( overviewTabSpec, CustomListFragment.class, null );
mFragmentTabHost.addTab ( searchTabSpec, TextFragment.class, null );
Log.d ( TAG, "onCreateView: added current tab to fragment manager and added tabs to FragmentTabHost" );
mFragmentTabHost.setCurrentTabByTag ( mCurrentTab );
Log.d ( TAG, "onCreateView: set current tab to " + mCurrentTab );
/* Make sure this fragment will listen to the user slecting a new ta
*/
Log.d ( TAG, "onCreateView: configuring tab host listener" );
mFragmentTabHost.setOnTabChangedListener ( this );
Log.d ( TAG, "onCreateView finished. Returning " + mRoot );
return ( mRoot );
}
@Override
public void onActivityCreated ( Bundle savedInstanceState ) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
Log.d(TAG, "onActivityCreated finished" );
}
@Override
public void onTabChanged ( String tabID ) {
/* Get the fragment manager associated with the tab controlling fragment
*/
Log.d ( TAG, tabID );
FragmentManager fragmentManager = this.getFragmentManager ( );
if ( fragmentManager.findFragmentByTag ( tabID ) == null && mCurrentTab.equals ( OVERVIEW_TAB_TAG ) ) {
fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, searchTabFragment, SEARCH_TAB_TAG ).commit ( );
mCurrentTab = SEARCH_TAB_TAG;
} else if ( fragmentManager.findFragmentByTag ( tabID ) == null && mCurrentTab.equals ( SEARCH_TAB_TAG ) ) {
fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
mCurrentTab = OVERVIEW_TAB_TAG;
}
}
}
package com.joshuaindustries.tabtest;
import android.support.v4.app.ListFragment;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* Created by Joshua on 18/12/2016.
*/
public class CustomListFragment extends ListFragment {
String TAG = "CustomListFragment";
Context fragmentContext;
Persons persons;
ArrayAdapter namesListAdapter;
public void setFragmentContext ( Context fragmentContext ) {
this.fragmentContext = fragmentContext;
}
public void setDataSource ( Persons persons ) {
this.persons = persons;
namesListAdapter = new ArrayAdapter ( fragmentContext, R.layout.tab_content_list, R.id.list_item_text_view, persons.getFirstNameArray ( ) );
setListAdapter ( namesListAdapter );
}
@Override
public void onListItemClick ( ListView listView, View itemView, int position, long id ) {
Intent showDetails = new Intent ( fragmentContext, details.class );
listView.getItemAtPosition ( position );
persons.putFieldsInIntent ( showDetails, position );
startActivity ( showDetails );
}
}
package com.joshuaindustries.tabtest;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TextView;
/**
* Created by Joshua on 15/12/2016.
*/
public class TextFragment extends Fragment {
String TAG = "TextFragment";
String UNIQUE_TAG;
private String mTabText;
private View mRoot;
private TextView mTextView;
public void setTabText ( String tabText ) {
mTabText = tabText;
}
@Override
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
/* Create all the view objects we need in memory and make sure the references to them in our class are correct
*/
mRoot = inflater.inflate ( R.layout.tab_content, container, false );
mTextView = ( TextView ) mRoot.findViewById ( R.id.tabTextView );
mTextView.setText ( mTabText );
return ( mRoot );
}
public void setUniqueTag ( String tag ) { UNIQUE_TAG = tag; }
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// this is really important in order to save the state across screen
// configuration changes for example
setRetainInstance(true);
}
}
CustomListFragment.java
import android.app.ListFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.FragmentTabHost;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.TabHost;
/**
* Created by Joshua on 12/12/2016.
*/
public class TabsFragment extends Fragment implements TabHost.OnTabChangeListener {
private String TAG = "TabsFragment";
/* Fixed tags for the different tabs */
public static final String OVERVIEW_TAB_TAG = "TAB_OVERVIEW";
public static final String SEARCH_TAB_TAG = "TAB_SEARCH";
/* Objects necessary to build activity views
*/
private LayoutInflater mInflater; // Used for building View objects in memory from our XML-resources
/* The views and other fragments our fragment will contain and helper variables for accessing them
*/
private View mRoot; // A reference to the root vie of our fragment
private FragmentTabHost mFragmentTabHost; // A reference to the tab host ( tab controlling ) view of our fragment
private String labelOverviewTab = "Overview";
private String labelSearchTab = "Searhc";
private CustomListFragment overviewTabFragment;
private TextFragment searchTabFragment;
/* Other fragment bookkeeping variables
*/
private String mCurrentTab; // Stores the tag of the currently visible tag
/* Data and adapters for our views */
private Persons personsInfo;
private ListAdapter namesListAdapter;
/* This method will get executed when the system wants to recreate our view
i.e. when the user returns or enters our tabs interface
It will return a reference to the root node of the views tree
*/
@Override
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
super.onCreateView ( inflater, container, savedInstanceState );
Log.d ( TAG, "onCreateView: starting ..." );
/* Create all the view objects we need in memory and make sure the references to them in our class are correct
*/
mRoot = inflater.inflate ( R.layout.tabs_fragment, container, false );
mFragmentTabHost = ( FragmentTabHost ) mRoot.findViewById ( android.R.id.tabhost );
Log.d ( TAG, "onCreateView: layouts inflated ... Attempting FragmentTabHost setup: ..." );
mFragmentTabHost.setup ( getContext ( ), getChildFragmentManager ( ), android.R.id.tabcontent );
Log.d ( TAG, "onCreateView: setup finished without errors ..." );
/* Initialize the tab host and make sure it's aware of all the tabs it has to manage
*/
TabHost.TabSpec overviewTabSpec = mFragmentTabHost.newTabSpec ( OVERVIEW_TAB_TAG );
TabHost.TabSpec searchTabSpec = mFragmentTabHost.newTabSpec ( SEARCH_TAB_TAG );
overviewTabSpec = overviewTabSpec.setContent ( R.id.overviewTab ).setIndicator ( labelOverviewTab );
searchTabSpec = searchTabSpec.setContent ( R.id.searchTab ).setIndicator ( labelSearchTab );
Log.d ( TAG, "onCreateView: created tab specs with TAG's " + overviewTabSpec.getTag ( ) + " & " + searchTabSpec.getTag ( ) );
Persons personsInfo = new Persons ( );
personsInfo.addPerson ( "Stanley", "Kubrick", 21 );
personsInfo.addPerson ( "Steven", "Spielberg", 20 );
personsInfo.addPerson ( "Quentin", "Tarantino", 18 );
personsInfo.addPerson ( "Joel", "Coen", 24 );
personsInfo.addPerson ( "Ethan", "Coen", 26 );
Log.d ( TAG, "onCreateView: initialized data" );
overviewTabFragment = new CustomListFragment ( );
overviewTabFragment.setFragmentContext ( getContext( ) );
overviewTabFragment.setDataSource ( personsInfo );
searchTabFragment = new TextFragment ( );
searchTabFragment.setUniqueTag ( "Search" );
searchTabFragment.setTabText ( "Here you will be able to SEARCH" );
Log.d ( TAG, "onCreateView: created fragments" );
mCurrentTab = OVERVIEW_TAB_TAG;
Log.d ( TAG, "onCreateView: set current tab variable to " + OVERVIEW_TAB_TAG );
getFragmentManager ( ).beginTransaction ( ).add ( overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
mFragmentTabHost.addTab ( overviewTabSpec, CustomListFragment.class, null );
mFragmentTabHost.addTab ( searchTabSpec, TextFragment.class, null );
Log.d ( TAG, "onCreateView: added current tab to fragment manager and added tabs to FragmentTabHost" );
mFragmentTabHost.setCurrentTabByTag ( mCurrentTab );
Log.d ( TAG, "onCreateView: set current tab to " + mCurrentTab );
/* Make sure this fragment will listen to the user slecting a new ta
*/
Log.d ( TAG, "onCreateView: configuring tab host listener" );
mFragmentTabHost.setOnTabChangedListener ( this );
Log.d ( TAG, "onCreateView finished. Returning " + mRoot );
return ( mRoot );
}
@Override
public void onActivityCreated ( Bundle savedInstanceState ) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
Log.d(TAG, "onActivityCreated finished" );
}
@Override
public void onTabChanged ( String tabID ) {
/* Get the fragment manager associated with the tab controlling fragment
*/
Log.d ( TAG, tabID );
FragmentManager fragmentManager = this.getFragmentManager ( );
if ( fragmentManager.findFragmentByTag ( tabID ) == null && mCurrentTab.equals ( OVERVIEW_TAB_TAG ) ) {
fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, searchTabFragment, SEARCH_TAB_TAG ).commit ( );
mCurrentTab = SEARCH_TAB_TAG;
} else if ( fragmentManager.findFragmentByTag ( tabID ) == null && mCurrentTab.equals ( SEARCH_TAB_TAG ) ) {
fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
mCurrentTab = OVERVIEW_TAB_TAG;
}
}
}
package com.joshuaindustries.tabtest;
import android.support.v4.app.ListFragment;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* Created by Joshua on 18/12/2016.
*/
public class CustomListFragment extends ListFragment {
String TAG = "CustomListFragment";
Context fragmentContext;
Persons persons;
ArrayAdapter namesListAdapter;
public void setFragmentContext ( Context fragmentContext ) {
this.fragmentContext = fragmentContext;
}
public void setDataSource ( Persons persons ) {
this.persons = persons;
namesListAdapter = new ArrayAdapter ( fragmentContext, R.layout.tab_content_list, R.id.list_item_text_view, persons.getFirstNameArray ( ) );
setListAdapter ( namesListAdapter );
}
@Override
public void onListItemClick ( ListView listView, View itemView, int position, long id ) {
Intent showDetails = new Intent ( fragmentContext, details.class );
listView.getItemAtPosition ( position );
persons.putFieldsInIntent ( showDetails, position );
startActivity ( showDetails );
}
}
package com.joshuaindustries.tabtest;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TextView;
/**
* Created by Joshua on 15/12/2016.
*/
public class TextFragment extends Fragment {
String TAG = "TextFragment";
String UNIQUE_TAG;
private String mTabText;
private View mRoot;
private TextView mTextView;
public void setTabText ( String tabText ) {
mTabText = tabText;
}
@Override
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
/* Create all the view objects we need in memory and make sure the references to them in our class are correct
*/
mRoot = inflater.inflate ( R.layout.tab_content, container, false );
mTextView = ( TextView ) mRoot.findViewById ( R.id.tabTextView );
mTextView.setText ( mTabText );
return ( mRoot );
}
public void setUniqueTag ( String tag ) { UNIQUE_TAG = tag; }
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// this is really important in order to save the state across screen
// configuration changes for example
setRetainInstance(true);
}
}
TextFragment.java
import android.app.ListFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.FragmentTabHost;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.TabHost;
/**
* Created by Joshua on 12/12/2016.
*/
public class TabsFragment extends Fragment implements TabHost.OnTabChangeListener {
private String TAG = "TabsFragment";
/* Fixed tags for the different tabs */
public static final String OVERVIEW_TAB_TAG = "TAB_OVERVIEW";
public static final String SEARCH_TAB_TAG = "TAB_SEARCH";
/* Objects necessary to build activity views
*/
private LayoutInflater mInflater; // Used for building View objects in memory from our XML-resources
/* The views and other fragments our fragment will contain and helper variables for accessing them
*/
private View mRoot; // A reference to the root vie of our fragment
private FragmentTabHost mFragmentTabHost; // A reference to the tab host ( tab controlling ) view of our fragment
private String labelOverviewTab = "Overview";
private String labelSearchTab = "Searhc";
private CustomListFragment overviewTabFragment;
private TextFragment searchTabFragment;
/* Other fragment bookkeeping variables
*/
private String mCurrentTab; // Stores the tag of the currently visible tag
/* Data and adapters for our views */
private Persons personsInfo;
private ListAdapter namesListAdapter;
/* This method will get executed when the system wants to recreate our view
i.e. when the user returns or enters our tabs interface
It will return a reference to the root node of the views tree
*/
@Override
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
super.onCreateView ( inflater, container, savedInstanceState );
Log.d ( TAG, "onCreateView: starting ..." );
/* Create all the view objects we need in memory and make sure the references to them in our class are correct
*/
mRoot = inflater.inflate ( R.layout.tabs_fragment, container, false );
mFragmentTabHost = ( FragmentTabHost ) mRoot.findViewById ( android.R.id.tabhost );
Log.d ( TAG, "onCreateView: layouts inflated ... Attempting FragmentTabHost setup: ..." );
mFragmentTabHost.setup ( getContext ( ), getChildFragmentManager ( ), android.R.id.tabcontent );
Log.d ( TAG, "onCreateView: setup finished without errors ..." );
/* Initialize the tab host and make sure it's aware of all the tabs it has to manage
*/
TabHost.TabSpec overviewTabSpec = mFragmentTabHost.newTabSpec ( OVERVIEW_TAB_TAG );
TabHost.TabSpec searchTabSpec = mFragmentTabHost.newTabSpec ( SEARCH_TAB_TAG );
overviewTabSpec = overviewTabSpec.setContent ( R.id.overviewTab ).setIndicator ( labelOverviewTab );
searchTabSpec = searchTabSpec.setContent ( R.id.searchTab ).setIndicator ( labelSearchTab );
Log.d ( TAG, "onCreateView: created tab specs with TAG's " + overviewTabSpec.getTag ( ) + " & " + searchTabSpec.getTag ( ) );
Persons personsInfo = new Persons ( );
personsInfo.addPerson ( "Stanley", "Kubrick", 21 );
personsInfo.addPerson ( "Steven", "Spielberg", 20 );
personsInfo.addPerson ( "Quentin", "Tarantino", 18 );
personsInfo.addPerson ( "Joel", "Coen", 24 );
personsInfo.addPerson ( "Ethan", "Coen", 26 );
Log.d ( TAG, "onCreateView: initialized data" );
overviewTabFragment = new CustomListFragment ( );
overviewTabFragment.setFragmentContext ( getContext( ) );
overviewTabFragment.setDataSource ( personsInfo );
searchTabFragment = new TextFragment ( );
searchTabFragment.setUniqueTag ( "Search" );
searchTabFragment.setTabText ( "Here you will be able to SEARCH" );
Log.d ( TAG, "onCreateView: created fragments" );
mCurrentTab = OVERVIEW_TAB_TAG;
Log.d ( TAG, "onCreateView: set current tab variable to " + OVERVIEW_TAB_TAG );
getFragmentManager ( ).beginTransaction ( ).add ( overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
mFragmentTabHost.addTab ( overviewTabSpec, CustomListFragment.class, null );
mFragmentTabHost.addTab ( searchTabSpec, TextFragment.class, null );
Log.d ( TAG, "onCreateView: added current tab to fragment manager and added tabs to FragmentTabHost" );
mFragmentTabHost.setCurrentTabByTag ( mCurrentTab );
Log.d ( TAG, "onCreateView: set current tab to " + mCurrentTab );
/* Make sure this fragment will listen to the user slecting a new ta
*/
Log.d ( TAG, "onCreateView: configuring tab host listener" );
mFragmentTabHost.setOnTabChangedListener ( this );
Log.d ( TAG, "onCreateView finished. Returning " + mRoot );
return ( mRoot );
}
@Override
public void onActivityCreated ( Bundle savedInstanceState ) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
Log.d(TAG, "onActivityCreated finished" );
}
@Override
public void onTabChanged ( String tabID ) {
/* Get the fragment manager associated with the tab controlling fragment
*/
Log.d ( TAG, tabID );
FragmentManager fragmentManager = this.getFragmentManager ( );
if ( fragmentManager.findFragmentByTag ( tabID ) == null && mCurrentTab.equals ( OVERVIEW_TAB_TAG ) ) {
fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, searchTabFragment, SEARCH_TAB_TAG ).commit ( );
mCurrentTab = SEARCH_TAB_TAG;
} else if ( fragmentManager.findFragmentByTag ( tabID ) == null && mCurrentTab.equals ( SEARCH_TAB_TAG ) ) {
fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
mCurrentTab = OVERVIEW_TAB_TAG;
}
}
}
package com.joshuaindustries.tabtest;
import android.support.v4.app.ListFragment;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* Created by Joshua on 18/12/2016.
*/
public class CustomListFragment extends ListFragment {
String TAG = "CustomListFragment";
Context fragmentContext;
Persons persons;
ArrayAdapter namesListAdapter;
public void setFragmentContext ( Context fragmentContext ) {
this.fragmentContext = fragmentContext;
}
public void setDataSource ( Persons persons ) {
this.persons = persons;
namesListAdapter = new ArrayAdapter ( fragmentContext, R.layout.tab_content_list, R.id.list_item_text_view, persons.getFirstNameArray ( ) );
setListAdapter ( namesListAdapter );
}
@Override
public void onListItemClick ( ListView listView, View itemView, int position, long id ) {
Intent showDetails = new Intent ( fragmentContext, details.class );
listView.getItemAtPosition ( position );
persons.putFieldsInIntent ( showDetails, position );
startActivity ( showDetails );
}
}
package com.joshuaindustries.tabtest;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TextView;
/**
* Created by Joshua on 15/12/2016.
*/
public class TextFragment extends Fragment {
String TAG = "TextFragment";
String UNIQUE_TAG;
private String mTabText;
private View mRoot;
private TextView mTextView;
public void setTabText ( String tabText ) {
mTabText = tabText;
}
@Override
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
/* Create all the view objects we need in memory and make sure the references to them in our class are correct
*/
mRoot = inflater.inflate ( R.layout.tab_content, container, false );
mTextView = ( TextView ) mRoot.findViewById ( R.id.tabTextView );
mTextView.setText ( mTabText );
return ( mRoot );
}
public void setUniqueTag ( String tag ) { UNIQUE_TAG = tag; }
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// this is really important in order to save the state across screen
// configuration changes for example
setRetainInstance(true);
}
}
Persons.java
package com.joshuaindustries.tabtest;
import android.content.Intent;
import java.util.ArrayList;
/**
* Created by Joshua on 17/12/2016.
*/
public class Persons {
public final static String PERSON_FIRST_NAME = "PERSON_FIRST_NAME";
public final static String PERSON_LAST_NAME = "PERSON_LAST_NAME";
public final static String PERSON_AGE = "PERSON_AGE";
public class Person {
String firstName;
String lastName;
int age;
public Person ( String firstName, String lastName, int age ) {
this.firstName = firstName; this.lastName = lastName; this.age = age;
}
public void setFirstName ( String newFirstName ) { firstName = newFirstName; }
public void setLastName ( String newLastName ) { lastName = newLastName; }
public void setAge ( int newAge ) { age = newAge; }
public String getFirstName ( ) { return ( firstName ); }
public String getLastName ( ) { return ( lastName ); }
public int getAge ( ) { return ( age ); }
}
ArrayList<Person> listOfPersons;
public Persons ( ) {
listOfPersons = new ArrayList<Person> ( );
}
public void addPerson ( String firstName, String lastName, int age ) { listOfPersons.add ( new Person ( firstName, lastName, age ) ); }
public String[] getFirstNameArray ( ) {
String[] firstNamesArray = new String [ listOfPersons.size ( ) ];
int index = 0;
for ( Person person : listOfPersons ) {
firstNamesArray [ index ] = person.getFirstName ( );
++ index;
}
return ( firstNamesArray );
}
public void putFieldsInIntent ( Intent intent, int position ) {
Person personAskedFor = listOfPersons.get ( position );
intent.putExtra ( PERSON_FIRST_NAME, personAskedFor.getFirstName ( ) );
intent.putExtra ( PERSON_LAST_NAME, personAskedFor.getLastName ( ) );
intent.putExtra ( PERSON_AGE, personAskedFor.getAge ( ) );
}
}
我完全不知道是什么导致了这个NullPointerException,因为我已经确认我所有的布局都正确地膨胀了,我在网上其他地方找不到有类似问题的人。我非常感谢你的帮助,特别是如果你能解释为什么我做的是错的
提前感谢,,
Joshua通过删除TabWidget中的android:tabStripEnabled=“true”解决了问题,通过删除TabWidget中的android:tabStripEnabled=“true”解决了问题。感谢您的快速响应,这可能是重复的,但我已经查看并尝试了该问题中的建议,但没有效果,你找到解决办法了吗?我得到同样的错误,但只有一个索尼xperia x设备。它可以在所有其他设备上正常工作,包括其他索尼设备。无法找出问题的根源。您可能想了解如何创建一个。可能重复的。感谢您的快速响应,但我已经查看并尝试了该问题中的建议,但没有结果。我,您找到任何解决方案了吗?我得到同样的错误,但只有一个索尼xperia x设备。它可以在所有其他设备上正常工作,包括其他索尼设备。无法找出问题的根源。您可能想了解如何创建一个。哇-很高兴您发现这样一个虚幻的消息,非常感谢!!哇-很高兴你发现了这样一条虚幻的信息,非常感谢!!