Reputation: 185
I'm getting the following error in my code:
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)
I'm using the following code of my Activity where I get a feed and once I get it I use the function LoadData to set the adapter to the 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);
}
}
}
This is my 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
}
}
And my Fragment where I'm using ListFragment to implements the listview
public class TabFragment extends ListFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.tabs, container, false);
}
}
It seems to be a problem when I set the adapter to listview in my activity. I need to set it in my MainActivity because there is my LoadData function. Should I use the adapter in my fragment? How? How could I implements LoadData then?
Thanks
EDIT:
Here is my tabs.xml where I take "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"/>
EDIT 2:
I think I should create the pager inside LoadData and send a Bundle with the "new" function and after that, to send again the args from the viewpager to the fragment. I tried it but I get errors creating the bundle.
This is my 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);
}
}
If I use adapter=new FeedAdapter(context,cursor,flag), What kind of "put" Do I have to used with the 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);
Upvotes: 1
Views: 1313
Reputation: 4646
You will need to move ListView
from tabs.xml
to activity_main.xml
(which is where it is looking when you call findViewById
. Then,
change <ListView android:id="@+id/lista"
to <ListView android:id="@android:id/list"
. More information can be found here.
If the xml file needs to be by itself, you can refer to this SO answer.
Upvotes: 1
Reputation: 258
lv.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.my_layout, R.id.just_an_id, MyList1));
this is the adapter I use for my lists in fragments and it's working great
Upvotes: 0