How can I manage fragment in non activity java class? - java

There are 2 different fragment in my project. I want to do inheritance these fragment from abstract class.But I cannot write correct code for FragmentManager to hide or show fragments. How can I do this?
Error : E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bengisu.bitirme, PID: 2580
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.bengisu.bitirme/com.example.bengisu.bitirme.MainActivity}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #0: Error inflating class fragment
Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.bengisu.bitirme.GameBoard: calling Fragment constructor caused an exception
at android.support.v4.app.Fragment.instantiate(Fragment.java:481)
at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3664)
at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:338)
at android.support.v4.app.BaseFragmentActivityApi14.onCreateView(BaseFragmentActivityApi14.java:39)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:67)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:777)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
at com.example.bengisu.bitirme.MainActivity.onCreate(MainActivity.java:30)
at android.app.Activity.performCreate(Activity.java:6666)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by: java.lang.reflect.InvocationTargetException
E/AndroidRuntime: at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.support.v4.app.Fragment.instantiate(Fragment.java:459)
... 34 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentManager android.support.v4.app.FragmentActivity.getSupportFragmentManager()' on a null object reference
at com.example.bengisu.bitirme.Board.<init>(Board.java:17)
at com.example.bengisu.bitirme.GameBoard.<init>(GameBoard.java:21)
... 37 more
Application terminated.
My abstract subclass : Board.java
public abstract class Board extends Fragment {
FragmentManager fm=((MainActivity)getActivity()).getSupportFragmentManager();
FragmentTransaction ft=fm.beginTransaction();
public abstract void Hide(Fragment fragment);
public abstract void Show(Fragment fragment);
}
First Fragment : GameBoard.java
public class GameBoard extends Board {
TextView t[]=new TextView[10];
TextView p[]=new TextView[3];
static float maxX,maxY;
Display mdispl;
Rain rain[]=new Rain[10];
Bucket bucket;
ImageView imgB;
ValueAnimator vaB;
int s=0;
public GameBoard getGameBoard(){
GameBoard gameBoard=(GameBoard) fm.findFragmentById(R.id.gameBoard);
return gameBoard;
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_game_board, container, false);
mdispl =getActivity().getWindowManager().getDefaultDisplay();
maxX = mdispl.getWidth();
maxY = mdispl.getHeight();
fm=getActivity().getSupportFragmentManager();
ft=fm.beginTransaction();
t[0]=view.findViewById(R.id.t0);
t[1] = view.findViewById(R.id.t1);
t[2] = view.findViewById(R.id.t2);
t[3] = view.findViewById(R.id.t3);
t[4] = view.findViewById(R.id.t4);
t[5] = view.findViewById(R.id.t5);
t[6] = view.findViewById(R.id.t6);
t[7] = view.findViewById(R.id.t7);
t[8] = view.findViewById(R.id.t8);
t[9] = view.findViewById(R.id.t9);
p[0] = view.findViewById(R.id.p0);
p[1] = view.findViewById(R.id.p1);
p[2] = view.findViewById(R.id.p2);
for (int i=0;i<10;i++){
rain[i]=new Rain(maxX,maxY);
rain[i].Move(t[i],0,0,5000);
}
imgB=view.findViewById(R.id.imageView);
bucket= new Bucket(imgB);
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
float initialX=event.getX();
if(initialX>getActivity().getWindowManager().getDefaultDisplay().getWidth()/2){
vaB= bucket.Move(null,imgB.getX(),getActivity().getWindowManager().getDefaultDisplay().getWidth()-imgB.getWidth()+150,1850);
}
else{
vaB=bucket.Move(null,imgB.getX(),-250,1850);
}
return false;
}
});
return view;
}
public void PauseBucket(){
vaB.pause();
}
#Override
public void Hide(Fragment fragment) {
ft.hide(fragment);
ft.commitNow();
}
#Override
public void Show(Fragment fragment) {
ft.show(fragment);
ft.commitNow();
}
}
Second Fragment : ScoreBoard.java
public class ScoreBoard extends Board{
//FragmentManager fm;
//FragmentTransaction ft;
ScoreBoard scoreBoard;
public ScoreBoard getScoreBoard(){
scoreBoard=(ScoreBoard)fm.findFragmentById(R.id.scoreBoard);
return scoreBoard;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
fm=getActivity().getSupportFragmentManager();
ft=fm.beginTransaction();
View view=inflater.inflate(fragment_score_board, container, false);
return view;
}
#Override
public void Hide(Fragment fragment) {
ft.hide(fragment);
ft.commitNow();
}
#Override
public void Show(Fragment fragment) {
ft.show(fragment);
ft.commitNow();
}
}
My MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView time,Gscore,Sscore;
FloatingActionButton repeat,pause,resume;
GameBoard gameBoard;
ScoreBoard scoreBoard;
Bucket bucket;
CountDownTimer timer;
int score=0;
String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = findViewById(R.id.time);
Gscore = findViewById(R.id.score);
Sscore = findViewById(R.id.Sscore);
repeat= findViewById(R.id.repeat);
pause = findViewById(R.id.pause);
resume = findViewById(R.id.resume);
gameBoard=gameBoard.getGameBoard();
scoreBoard=scoreBoard.getScoreBoard();
Game(60000,0);
repeat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scoreBoard.Hide(scoreBoard);
gameBoard.Show(gameBoard);
Gscore.setVisibility(View.VISIBLE);
//gameBoard.StartAgain();
Game(60000,0);
// flipper.showNext();
bucket.bucket.setX(getWindowManager().getDefaultDisplay().getWidth()/2-100);
}
});
}
public void Game(long m,int s){
//gameFragment.s=s;
timer= new CountDownTimer(m,1000) {
public void onTick(long millisUntilFinished) {
scoreBoard.Hide(scoreBoard);
gameBoard.Show(gameBoard);
score = gameBoard.s;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d",
(millisUntilFinished / 1000) / 60,
(millisUntilFinished / 1000) % 60);
time.setText(""+timeLeftFormatted);
Gscore.setText(""+score);
if(millisUntilFinished<=30000){
time.setTextColor(Color.BLACK);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
time.setTextColor(Color.WHITE);
}
},500);
}
else time.setTextColor(Color.BLACK);
}
public void onFinish() {
scoreBoard.Show(scoreBoard);
gameBoard.Hide(gameBoard);
//flipper.showNext();
Gscore.setVisibility(View.INVISIBLE);
Sscore.setText(name+"'s Score : "+Gscore.getText());
}
};
timer.start();
}
}

I don't get what you mean exactly, but I see one problem in this line
FragmentManager fm=((MainActivity)getActivity()).getSupportFragmentManager();
It seems likegetActivity() here returned null so the error said:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentManager android.support.v4.app.FragmentActivity.getSupportFragmentManager()' on a null object reference
at com.example.bengisu.bitirme.Board.<init>(Board.java:17)
at com.example.bengisu.bitirme.GameBoard.<init>(GameBoard.java:21)
Maybe you should try to init this variable in onActivityCreated

You have problem in instantiation fragment.
Also trace shown problem, take a look at line 0 in your xml of your MainActivity class
Unable to start activity
ComponentInfo{com.example.bengisu.bitirme/com.example.bengisu.bitirme.MainActivity
}: android.view.InflateException: Binary XML file line #0: Binary XML file
line #0: Error inflating class fragment
Also this is not correct way for instantiation fragment.
Following link should help you in working with framents
https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments
In short answer you should create your framgne in following way:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.frame_layout, new YourFragment());
// or ft.add(R.id.frame_layout, new FooFragment());
ft.commit();

Related

TextView inside Fragment in ViewPager is null on orientation change

I have a MainActivity inside I create ViewPager withFragments. I am using savedInstanceState to store values to set TextView after orientation changed. I also want to change value e.g. using button in MainActivity. Button works properly, but if I change the orientation then Button cannot set TextView in Fragment because TextView is now null.
MyFragment
public class MyFragment extends Fragment {
private TextView textView;
private String info;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.item_weather, container, false);
textView = view.findViewById(R.id.text_view);
Bundle bundle = getArguments();
info = bundle.getString("info");
setInfo(info);
return view;
}
public void setInfo(String info) {
this.info = info;
textView.setText(info); //here is the error
}
}
In MainActivity.java in OnCreate
myFragment = new MyFragment();
viewPager = findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(10);
List<Fragment> fragments = new ArrayList<>();
fragments.add(myFragment);
pagerAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
viewPager.setAdapter(pagerAdapter);
MyPagerAdapter looks like this:
public class MyPageAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
}
As I said everything works, but after orientation chage if I use Button I got an error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Any ideas how to solve this?
edit:
full error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app.myapp, PID: 15400
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.app.myapp.fragments.myFragment.setInfo(myFragment.java:53)
at com.example.app.myapp.MainActivity.onOptionsItemSelected(MainActivity.java:195)
at android.app.Activity.onMenuItemSelected(Activity.java:3543)
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:407)
at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:63)
at android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:203)
at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:780)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:127)
at android.widget.AdapterView.performItemClick(AdapterView.java:318)
at android.widget.AbsListView.performItemClick(AbsListView.java:1159)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3136)
at android.widget.AbsListView$3.run(AbsListView.java:4052)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Into the fragment try to initialize the textView in the on the onViewCreated method:
#Override
public View onViewCreated(view: View, savedInstanceState: Bundle) {
// Your initialization code here
}
Solution:
Ok, EpicPandaForce thanks for hints.
To solve this i used in MainActivity
#Override
protected void onResume() {
super.onResume();
viewPager.setAdapter(pagerAdapter);
}
#Override
protected void onPause() {
super.onPause();
viewPager.setAdapter(null);
}

Open Close Maps with button (change layouts)

I am trying to open and close maps (changing layouts) with a button.
I have a button in MainActivity which opens SecondActivity and this sets maps_layout correct.
I have a button on the maps. This switches to another layout correctly.
When I want to switch back, I get Fatal Exception.
My Code:
public class Game extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mapy();
}
public void mapy() {
setContentView(R.layout.mapy_test);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map_test);
mapFragment.getMapAsync(this);
Button changetocam = (Button) findViewById(R.id.changetocam);
changetocam.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cam();
}
});
}
public void cam() {
setContentView(R.layout.ingame_masteroverlay_layout);
Button changetomap = (Button) findViewById(R.id.changetomap);
changetomap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mapy();
}
});
}
}
Here is the error log:
`FATAL EXCEPTION: main Process: auftour.mrorhan.probieren, PID: 2689 android.view.InflateException: Binary XML file line #6: Binary XML file line #6: Error inflating class fragment Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class fragment Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Duplicate id 0x7f0f010b, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.SupportMapFragment`
I think the error is because I don't close the mapy_test layout, so I have double id, when I try to connect to the map again.
// Try this it is working for me
View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (v != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(v);
}
try
{
v = inflater.inflate(R.layout.mapy_test, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
return v;
}
So guys, i solve my Problem. I worked with frames and with an extra frame containerlayout. If someone have the same Problem I can write my own code.

how to re-populate the Pagerview view using PagerAdapter?

Issue
First time it works fine. this app download image from the internet and save into external storage.
I want to make a method when i call the method then it will repopulate the image from external storage and set new adapter to show the all images on PagerView.
In simple words i want to refresh the pagerview screens view. on app
start there is 3 images in sdcard. and when i press button then there
is 4 images in sdcard. it should update/refresh the view.
This the custom adapter class
public class CustomSwipeAdapter extends PagerAdapter {
static ImageView i1;
String pdfName;
static Bitmap[] bmp ;
private Context ctx;
private LayoutInflater layoutInflater;
public CustomSwipeAdapter(Context ctx) {
this.ctx =ctx;
}
#Override
public int getCount() {
bmp=Picgraber();
return bmp.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view==(LinearLayout)object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
//Picgraber();
layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View item_view = layoutInflater.inflate(R.layout.swipe_layout,container,false);
i1 = (ImageView)item_view.findViewById(R.id.swipeimageview);
TextView t1 = (TextView)item_view.findViewById(R.id.swipetextview);
// i1.setImageResource(images[position]);
i1.setImageBitmap(bmp[position]);
i1.setTag(imagesstr[position]);
t1.setText("image "+ position);
pdfName = String.valueOf(i1.getResources());
Log.d("pdfname", pdfName);
Log.d("position", String.valueOf(position));
container.addView(item_view);
return item_view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout)object);
}
public Bitmap[] Picgraber(){
ArrayList<Bitmap> list = new ArrayList<Bitmap>();
File file= new File("/sdcard/com.shah.tabs/");
File[] folders=file.listFiles();
for(File ff:folders){
File it=new File(file.getPath()+File.separator+ff.getName()+File.separator+"image"+File.separator+ff.getName()+".png");
// Log.w("folder with path",it.getPath());
list.add(BitmapFactory.decodeFile(it.getPath()));
}
Bitmap[] Array = list.toArray(new Bitmap[list.size()]);
return Array;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
public void update(){
bmp = Picgraber();
this.notifyDataSetChanged();
}
}
This is the onCreate method of the activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_books);
packageFolder = new File(Environment.getExternalStorageDirectory() + File.separator + getApplicationContext().getPackageName());
if (!packageFolder.exists()) {
packageFolder.mkdir();
}
viewPager = (ViewPager) findViewById(R.id.viewpager);
adapter = new CustomSwipeAdapter(this);
viewPager.setAdapter(adapter);
Log.d("curritem", String.valueOf(viewPager.getCurrentItem()));
viewPager.setPageTransformer(true, new ZoomOutSlideTransformer());
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
pos = position;
Log.d("onpagechange", String.valueOf(pos));
Log.d("imagename", String.valueOf(CustomSwipeAdapter.i1.getTag()));
}
});
viewPager.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
x1 = event.getX();
y1 = event.getY();
break;
}
case MotionEvent.ACTION_UP: {
x2 = event.getX();
y2 = event.getY();
if (x1 < x2) {
}
if (x1 > x2) {
}
if (y1 < y2) {
}
if (y1 > y2 + 100) {
downtoupswipe();
}
break;
}
}
return false;
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, 1);
}
});
}
This the logcat of the application when crash
10-10 11:00:50.388 16816-16816/com.shah.tabs E/InputEventReceiver: Exception dispatching input event.
10-10 11:00:50.389 16816-16816/com.shah.tabs E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
10-10 11:00:50.390 16816-16816/com.shah.tabs E/MessageQueue-JNI: java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 2, found: 3 Pager id: com.shah.tabs:id/viewpager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.shah.tabs.CustomSwipeAdapter
at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2114)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
10-10 11:00:50.390 16816-16816/com.shah.tabs D/AndroidRuntime: Shutting down VM
10-10 11:00:50.393 16816-16816/com.shah.tabs E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shah.tabs, PID: 16816
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 2, found: 3 Pager id: com.shah.tabs:id/viewpager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.shah.tabs.CustomSwipeAdapter
at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2114)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
**
Call from activity fab button
**
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
adapter.update();
}
});
Using the array of bitmaps have a performance issues. You can use any ImageLoader libs to do display image.
The Universal ImageLoader has methods to display local images
make some changes in this class
CustomSwipeAdapter
#Override
public int getCount() {
return imagesstr.length();
}
//add this method
public void setImages(String image[]){
imagesstr = image;
this.notifyDataSetChanged();
}
to display image use the imageLoader as suggested earlier
Just take a look at the Exception message you got here. It says:
java.lang.IllegalStateException: The application's PagerAdapter
changed the adapter's contents without calling
PagerAdapter#notifyDataSetChanged! Expected adapter item count: 2,
found: 3
It is pretty clear from the Exception message that while refreshing your PagerView, you are adding new images but you are not telling the adapter that the data which it is going to populate has been changed. As a result, the adapter expecting to just populate 2 images find 3 images and your application crashes.
So whenever you add a new image you need to explicitly call adapter.notifyDataSetChanged() to tell the adpater that a new image has been added which would eventually solve this issue.

NullPointerException when showing a ViewPager a second time

I am using a ViewPager fragment which has two fragments as children. This works great, however when I replace the ViewPager fragment by another fragment and replace this fragment by the ViewPager fragment my application crashes with the following NullPointerException:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:667)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1319)
at android.view.View.dispatchRestoreInstanceState(View.java:13756)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2888)
at android.view.View.restoreHierarchyState(View.java:13734)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:468)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1094)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5294)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
My ViewPager fragment consists of the following source code instanciating the two child fragments in case they are null. Furthermore, the ViewPagerAdapter implementation is instanciated and assigned to the ViewPager.
public class ConnectionPasswordViewPagerFragment extends Fragment
{
private ViewPager vpConnectionPassword;
private ConnectionPasswordViewPagerAdapter paConnectionPassword;
private ConnectionPasswordGeneratorMACAddress passwordGeneratorMACAddress;
private ConnectionPasswordGeneratorSerialNumber passwordGeneratorSerialNumber;
public ConnectionPasswordViewPagerFragment()
{
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if ((this.passwordGeneratorSerialNumber == null) && (this.passwordGeneratorMACAddress == null))
{
this.passwordGeneratorMACAddress = new ConnectionPasswordGeneratorMACAddress();
this.passwordGeneratorSerialNumber = new ConnectionPasswordGeneratorSerialNumber();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_connection_password_view_pager, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
/*if (this.paConnectionPassword == null)
{*/
this.paConnectionPassword = new ConnectionPasswordViewPagerAdapter(this.getChildFragmentManager(), this.getActivity(), this.passwordGeneratorMACAddress, this.passwordGeneratorSerialNumber);
//}
this.vpConnectionPassword = (ViewPager) this.getActivity().findViewById(R.id.vpConnectionPassword);
this.vpConnectionPassword.setAdapter(this.paConnectionPassword);
}
}
The ViewPagerAdapter shown below implementation keeps the reference to the child fragments in an ArrayList and implements the metods getItem(), getCount() as well as getPageTitle(). The class ViewPagerFragment simply extends the support Fragment class and provides the abstract method getPageTitleStringID() implemented by the child fragments.
public class ConnectionPasswordViewPagerAdapter extends FragmentStatePagerAdapter
{
private static final byte NUMBER_OF_FRAGMENTS = (byte) 2;
private ArrayList<ViewPagerFragment> childFragments;
private Activity displayActivity;
public ConnectionPasswordViewPagerAdapter(FragmentManager fragmentMgm, Activity displayAct, ConnectionPasswordGeneratorMACAddress generatorMACAddress, ConnectionPasswordGeneratorSerialNumber generatorSerialNumber)
{
super(fragmentMgm);
this.childFragments = new ArrayList<>(ConnectionPasswordViewPagerAdapter.NUMBER_OF_FRAGMENTS);
this.setDisplayActivity(displayAct);
if (generatorMACAddress != null)
{
this.childFragments.add(generatorMACAddress);
}
if (generatorSerialNumber != null)
{
this.childFragments.add(generatorSerialNumber);
}
}
public Activity getDisplayActivity()
{
return this.displayActivity;
}
public void setDisplayActivity(Activity value)
{
this.displayActivity = value;
}
#Override
public Fragment getItem(int position)
{
return this.childFragments.get(position);
}
#Override
public int getCount()
{
return ConnectionPasswordViewPagerAdapter.NUMBER_OF_FRAGMENTS;
}
#Override
public CharSequence getPageTitle(int position)
{
return this.getDisplayActivity().getString(this.childFragments.get(position).getPageTitleStringID());
}
}
Thanks for your help!
I fixed the issue by simply creating the fragment containing the view pager every time I call the support fragment manager's replace method.
public void onSwitchToConnectionPasswordGenerator(View clickedView)
{
this.fragConnectionPassword = new ConnectionPasswordViewPagerFragment();
this.getSupportFragmentManager().beginTransaction().replace(R.id.flFragmentContainer, this.fragConnectionPassword).commitAllowingStateLoss();
}
I think your Viewpager is in Fragment, and this fragment have setRetainInstance set to true (i have this error too when i try to retain the parent fragment)
Better way is to you can check for FragmentManager to get Fragment if its there, if not then create a new instance as follows:
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag("YourFragmentName");
if(fragment == null)
fragment = new YourFragment();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.replace(Your_Fragmnet_Container_Layout_id, fragment, fragment.getClass().getSimpleName());
fragmentTransaction.commit;

IllegalArgumentException caused by binary XML file (Android)

i have a basic navigation with 3 tabs. One of them contains a fragment with google maps in it. However the navigation isn't good, it keeps crashing after i select the tab for the second time.
It says it is because of the XML file of the maps which in my opinion doesn't have anything wrong. Can anyone see my error which i am blinded for right now?
Logcat :
android.view.InflateException: Binary XML file line #7: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at com.example.dell.animalz.MapsFragment.onCreateView(MapsFragment.java:22)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1504)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1297)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
at
android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
at
android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:482)
at
android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:555)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at com.example.dell.animalz.HomeActivity.onTabSelected(HomeActivity.java:67)
at com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:674)
at com.android.internal.app.ActionBarImpl$TabImpl.select(ActionBarImpl.java:1217)
at
com.android.internal.widget.ScrollingTabContainerView$TabClickListener.onClick(ScrollingTabContainerView.java:976)
at android.view.View.performClick(View.java:4637)
at android.view.View$PerformClick.run(View.java:19422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5586)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #7: Duplicate id 0x7f070067, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:297)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691)
            
HomeActivity.java
public class HomeActivity extends FragmentActivity implements ActionBar.TabListener {
ViewPager mViewPager = null;
private TabsMenuAdapter mAdapter;
private ActionBar actionBar;
private String []tabs = {"News", "Animalz", "Maps"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_layout);
mViewPager = (ViewPager)findViewById(R.id.viewpager1);
actionBar = getActionBar();
mAdapter = new TabsMenuAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for(String tab_names : tabs){
actionBar.addTab(actionBar.newTab().setText(tab_names).setTabListener(this));
}
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener(){
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
}
Maps.java
public class MapsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.maps_layout, container, false);
return rootView;
}
}
Maps.xml
<?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">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
</RelativeLayout>
Any help would be appreciated, thanks in advance !
You have to remove the MapFragment in the onDestroyView() method of the Fragment that contains the map, with referring to this answer, you must do the following:
// override the onDestroyView of the fragment
#Override
public void onDestroyView() {
super.onDestroyView();
MapFragment f = (MapFragment) getFragmentManager()
.findFragmentById(R.id.the_map);
if (f != null)
getFragmentManager().beginTransaction().remove(f).commit();
}
Every time check your parent view empty or not. If yes then remove. Change your Maps.java.
private static View view;
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup group,Bundle bundle)
{
if(view!=null)
{
ViewGroup parent =(ViewGroup)view.getParent();
if(parent!=null)
parent.removeView(view);
}
try{
view=inflater.inflate(R.layout.maps, group, false);
........
}
catch(Exception e)
{
Log.e("ERROR", ""+e);
}
return view;
}

Categories