Reputation: 3
After searching through a lot of answer here, i cant seem to solve my problem. First i had a problem using findViewById to get a listView from a fragment, to solve this i had to inflate the layout of the fragment first and use "mContainer.findViewById..".
I don't know if that is the cause of the viewpager not updating (or the listview itself).
My OnCreate:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myContainer = getLayoutInflater().inflate(R.layout.frag_links,null);
root = (RelativeLayout) findViewById(R.id.rootLayout);
root.post(new Runnable() {
@Override
public void run() {
Rect rect = new Rect();
Window win = getWindow(); // Get the Window
win.getDecorView().getWindowVisibleDisplayFrame(rect);
// Get the height of Status Bar
int statusBarHeight = rect.top;
// Get the height occupied by the decoration contents
int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
// Calculate titleBarHeight by deducting statusBarHeight from contentViewTop
int titleBarHeight = contentViewTop - statusBarHeight;
Log.i("MY", "titleHeight = " + titleBarHeight + " statusHeight = " + statusBarHeight + " contentViewTop = " + contentViewTop);
// By now we got the height of titleBar & statusBar
// Now lets get the screen size
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenHeight = metrics.heightPixels;
screenWidth = metrics.widthPixels;
Log.i("MY", "Actual Screen Height = " + screenHeight + " Width = " + screenWidth);
// Now calculate the height that our layout can be set
// If you know that your application doesn't have statusBar added, then don't add here also. Same applies to application bar also
int layoutHeight = screenHeight - (titleBarHeight + statusBarHeight);
Log.i("MY", "Layout Height = " + layoutHeight);
// Lastly, set the height of the layout
// LinearLayout.LayoutParams rootParams = (android.widget.LinearLayout.LayoutParams)root.getLayoutParams();
// rootParams.height = layoutHeight;
// root.setLayoutParams(rootParams);
}
});
// (array => res/values/strings)
titulosMenu = getResources().getStringArray(R.array.drawer_items);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
lvdrawer = (ListView) findViewById(R.id.lvdrawer);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
View header = getLayoutInflater().inflate(R.layout.header, null);
lvdrawer.addHeaderView(header);
itemsMenu = new ArrayList<ItemDrawer>();
for (int i = 0; i < titulosMenu.length; i++) {
itemsMenu.add(new ItemDrawer(titulosMenu[i]));
}
AdaptadorDrawer adapter=new AdaptadorDrawer(this, R.layout.filaitem, itemsMenu);
lvdrawer.setAdapter(adapter);
lvdrawer.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> a, View v, int posicion,
long id) {
Intent intent;
switch (posicion) {
// case 1:
// break;
// case 2:
// break;
case 3:
intent = new Intent(MainActivity.this, Contacto.class);
startActivity(intent);
break;
}
drawerLayout.closeDrawers();
}
});
drawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
GravityCompat.START);
toggle = new ActionBarDrawerToggle(this, // Activity
drawerLayout, // Panel del Navigation Drawer
new Toolbar(MainActivity.this), // Icono que va a utilizar
R.string.menu, // Descripcion al abrir el drawer
R.string.app_name // Descripcion al cerrar el drawer
) {
@Override
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(R.string.menu);
invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View view) {
getActionBar().setTitle(TITULOREEM);
invalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(toggle);
pager = (ViewPager)findViewById(R.id.viewPager);
pager.setAdapter(new AdaptadorPager(getSupportFragmentManager()));
TitlePageIndicator titleIndicator = (TitlePageIndicator)findViewById(R.id.titulo);
titleIndicator.setViewPager(pager);
LinearNews=(LinearLayout)findViewById(R.id.LinearNoticias);
putLinks();
}
}
Here is the problem, i call this method but nothing happens. if i dont use myContainer.findViewById the program will crash showing a nullpointerexception as it couldnt find the ListView:
private void putLinks() {
lvLinks = (ListView)myContainer.findViewById(R.id.lvlinksnuevo);
listaLinks = new ArrayList<Link>();
listaLinks.add(new Link("test", "test", "link_afijma"));
AdaptadorLinks adaplink = new AdaptadorLinks(MainActivity.this, R.layout.linealinks , listaLinks);
lvLinks.setAdapter(adaplink);
pager.getAdapter().notifyDataSetChanged();
}
I dont know wheter you need this or not, but here it is anyway:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
toggle.syncState();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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.
if (toggle.onOptionsItemSelected(item)) {
return true;
}
int id = item.getItemId();
if (id == R.id.menuDrawer) {
drawerLayout.openDrawer(Gravity.START);
return true;
}
return super.onOptionsItemSelected(item);
}
Here is my pager adapter (I tried using FragmentStatePagerAdapter too):
public class AdaptadorPager extends FragmentPagerAdapter {
private final String[] titles = { "Presentación", "Noticias", "Links"};
public AdaptadorPager(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FragmentoPresentacion();
case 1:
return new FragmentoNoticias();
case 2:
return new FragmentoLinks();
}
return null;
}
@Override
public int getCount() {
return titles.length;
}
// 3º Poner en el adaptador el método que devuelve la cadena del titulo
// Devuelve el título segun nos coloquemos en uno u otro fragmento
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
Here is my ListView adapter:
public class AdaptadorLinks extends ArrayAdapter<Link>{
private int layoutFila;
private LayoutInflater inflater;
private Context context;
public AdaptadorLinks(Context ctx, int resourceId, ArrayList<Link> objects) {
super(ctx, resourceId, objects);
layoutFila = resourceId;
inflater = LayoutInflater.from(ctx);
context=ctx;
}
@Override
public View getView(int position, View fila, ViewGroup parent) {
fila = inflater.inflate(layoutFila, null );
Link link = getItem(position);
ImageView iconfila=(ImageView) fila.findViewById(R.id.imageLineaLinks);
TextView titulofila = (TextView)fila.findViewById(R.id.tvLineaLinks1);
TextView urlfila = (TextView)fila.findViewById(R.id.tvLineaLinks2);
int id=context.getResources().getIdentifier(link.getImagen(), "drawable", context.getPackageName());
iconfila.setImageResource(id);
titulofila.setText(link.getTitulo());
urlfila.setText(link.getUrl());
return(fila);
}
}
the xmls for the design are:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Content -->
<RelativeLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background">
<HorizontalScrollView
android:id="@+id/horizontalScrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#70000000" >
<LinearLayout
android:id="@+id/LinearNoticias"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
<com.viewpagerindicator.TitlePageIndicator
android:id="@+id/titulo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/horizontalScrollView1"
android:background="#95000000" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/titulo"
android:background="#80000000" />
</RelativeLayout>
<!-- Navigation Drawer -->
<ListView
android:id="@+id/lvdrawer"
android:layout_width="270dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/list_background"/>
</android.support.v4.widget.DrawerLayout>
Fragment for links:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutFragLinks"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/lvlinksnuevo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="#90000000" >
</ListView>
</RelativeLayout>
And the line for the LV adapter:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imageLineaLinks"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="@drawable/link_emmen" />
<TextView
android:id="@+id/tvLineaLinks1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="@+id/imageLineaLinks"
android:layout_toRightOf="@+id/imageLineaLinks"
android:gravity="center"
android:text="TextView"
android:textColor="@color/white"
android:textSize="15sp" />
<TextView
android:id="@+id/tvLineaLinks2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tvLineaLinks1"
android:layout_alignStart="@+id/tvLineaLinks1"
android:layout_below="@+id/tvLineaLinks1"
android:gravity="center"
android:text="TextView"
android:textColor="@color/white"
android:textSize="12sp" />
</RelativeLayout>
Thanks in advance. I hope someone can help me out.
My new fragment code:
public class FragmentoLinks extends Fragment {
private ListView lvLinks;
private ArrayList<Link> listaLinks;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.frag_links, container, false);
lvLinks = (ListView)getActivity().findViewById(R.id.lvlinksnuevo);
listaLinks = new ArrayList<Link>();
listaLinks.add(new Link("test", "test", "link_afijma"));
AdaptadorLinks adaplink = new AdaptadorLinks(getActivity(), R.layout.linealinks , listaLinks);
lvLinks.setAdapter(adaplink);
return layout;
}
}
I tried getView() instead getActivity() same result.
This is the error i get now:
04-15 12:44:41.192: E/AndroidRuntime(32713): FATAL EXCEPTION: main
04-15 12:44:41.192: E/AndroidRuntime(32713): Process: com.aeioumusica.aplireem, PID: 32713
04-15 12:44:41.192: E/AndroidRuntime(32713): java.lang.NullPointerException
04-15 12:44:41.192: E/AndroidRuntime(32713): at com.aeioumusica.aplireem.FragmentoLinks.onCreateView(FragmentoLinks.java:32)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:953)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1499)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:488)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.support.v4.view.ViewPager$3.run(ViewPager.java:249)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.view.Choreographer.doCallbacks(Choreographer.java:603)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.view.Choreographer.doFrame(Choreographer.java:572)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.os.Handler.handleCallback(Handler.java:733)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.os.Handler.dispatchMessage(Handler.java:95)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.os.Looper.loop(Looper.java:157)
04-15 12:44:41.192: E/AndroidRuntime(32713): at android.app.ActivityThread.main(ActivityThread.java:5356)
04-15 12:44:41.192: E/AndroidRuntime(32713): at java.lang.reflect.Method.invokeNative(Native Method)
04-15 12:44:41.192: E/AndroidRuntime(32713): at java.lang.reflect.Method.invoke(Method.java:515)
04-15 12:44:41.192: E/AndroidRuntime(32713): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
04-15 12:44:41.192: E/AndroidRuntime(32713): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
04-15 12:44:41.192: E/AndroidRuntime(32713): at dalvik.system.NativeStart.main(Native Method)
Upvotes: 0
Views: 179
Reputation: 2741
Although a Fragment
is implemented as an object that's independent from
an Activity
and can be used inside multiple activities, a given
instance of a Fragment
is directly tied to the activity that contains
it.
Specifically, the fragment can access the Activity
instance with
getActivity()
and easily perform tasks such as find a view in the
Activity
layout:
View listView = getActivity().findViewById(R.id.list);
Likewise, your Activity
can call methods in the Fragment
by acquiring a
reference to the Fragment
from FragmentManager
, using findFragmentById()
or findFragmentByTag()
. For example:
ExampleFragment fragment = (ExampleFragment)
getFragmentManager().findFragmentById(R.id.example_fragment);
Upvotes: 0
Reputation: 15388
myContainer = getLayoutInflater().inflate(R.layout.frag_links,null);
This creates a new RelativeLayout
with the fragment layout, that is not attached anywhere, is not shown on screen. It certainly does not return the component you want to modify, which is created as part of the fragment.
From your code, you want to modify the ListView
inside one of the fragments. That particular fragment, however, may not even be displayed, because ViewPager
decides when your fragments get created. The fragment may not yet exist when your code is executed or it may not be on screen.
Most importantly, however, the fragment is not always part of the view hierarchy of your activity. Hence findViewById()
on the activity won't find anything since the view may not exist at all.
Move your link update code into the fragment and use layout.findViewById()
inside the fragment after inflating the fragment layout. This will attach the ListAdapter
to the correct ListView
inside the fragment after it is inflated from the layout XML.
Upvotes: 0
Reputation: 1992
In a fragment you should be doing your view setup inside onCreateView()
, and then calling
getView().findViewById()
elsewhere.
This is because the lifecycle of a fragment is different from an activity.
See http://developer.android.com/guide/components/fragments.html#Creating for more information.
Upvotes: 1