2017-08-20 4 views
2

gibt es eine MainActivity mit Fragment mit dem Namen FragmentOne. Ich habe eine Liste von Elementen in diesem Fragment und diese Daten sind in meiner Datenbank speichernFragment nach dem Ändern der Daten in der Datenbank aktualisieren

ich mache Änderungen von NavigationView in MainActivity .. Ich versuche, alle Zeilen aus meiner Datenbank zu löschen. es funktioniert, aber danach muss ich meine FragmentOne aktualisieren, wie kann ich die FragmentOne UI aktualisieren?

Ich habe eine Methode namens updateUI in meinem FragmentOne, aber wie könnte ich auf diese Methode zugreifen? wenn ich diese methode mache public geht alles schief!

Ich testete verschiedene Möglichkeiten, aber gescheitert .. kann mir jemand sagen, wie kann ich das tun?

MainActivity:

public class MainActivity extends AppCompatActivity { 

private DrawerLayout mDrawerLayout; 
private TabLayout tabLayout; 
private ViewPager viewPager; 
private Detail mDetail; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //////// TOOLBAR 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    ActionBar actionBar = getSupportActionBar(); 
    actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); 
    actionBar.setDisplayHomeAsUpEnabled(true); 

    ///////// DRAWER 
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 

    NavigationView navigationView = 
      (NavigationView) findViewById(R.id.navigation_view); 
    navigationView.setNavigationItemSelectedListener 
      (new NavigationView.OnNavigationItemSelectedListener() { 
       @Override 
       public boolean onNavigationItemSelected(MenuItem menuItem) { 
        switch (menuItem.getItemId()) { 
         case R.id.nav_item_one: 
          return false; 

         case R.id.nav_item_two: 


          AlertDialog.Builder alert_delete = new AlertDialog.Builder(
            MainActivity.this); 
          alert_delete.setTitle("Alert!"); 
          alert_delete.setMessage(R.string.alert_delete_all); 
          alert_delete.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
           @Override 
           public void onClick(DialogInterface dialog, int which) { 

            DetailLab.get(getApplicationContext()).deleteAllDetail(); 

            FragmentOne fragmentOne = new FragmentOne(); 
            fragmentOne.getFragmentManager().beginTransaction().replace(R.id.card_view, fragmentOne) 
              .commit(); 

              dialog.dismiss(); 
           } 
          }); 
          alert_delete.setNegativeButton("No", new DialogInterface.OnClickListener() { 
           @Override 
           public void onClick(DialogInterface dialog, int which) { 
            dialog.dismiss(); 
           } 
          }); 
          alert_delete.show(); 

          return false; 
.. 
.. 
         case R.id.nav_item_nine: 
          finish(); 

          default: 
           return false; 
        } 
       } 
      }); 

    viewPager = (ViewPager) findViewById(R.id.viewpager); 
    setupViewPager(viewPager); 

    tabLayout = (TabLayout) findViewById(R.id.tablayout); 
    tabLayout.setupWithViewPager(viewPager); 
    setupTabIcons(); 
} 


private void setupViewPager(ViewPager viewPager) { 
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); 
    adapter.addFragment(new FragmentOne(), "ONE"); 
    adapter.addFragment(new FragmentTwo(), "TWO"); 
    viewPager.setAdapter(adapter); 
} 

class ViewPagerAdapter extends FragmentPagerAdapter { 
    private final List<Fragment> mFragmentList = new ArrayList<>(); 
    private final List<String> mFragmentTitleList = new ArrayList<>(); 

    public ViewPagerAdapter(FragmentManager manager) { 
     super(manager); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragmentList.get(position); 
    } 

    @Override 
    public int getCount() { 
     return mFragmentList.size(); 
    } 

    public void addFragment(Fragment fragment, String title) { 
     mFragmentList.add(fragment); 
     mFragmentTitleList.add(title); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return null; 
    } 
} 


@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    int id = item.getItemId(); 

    switch (id) { 
     case android.R.id.home: 
      mDrawerLayout.openDrawer(GravityCompat.START); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

} 

hier ist meine Methode zum Löschen aller Zeilen aus der Datenbank in einer anderen Klasse namens DetailLab:

public void deleteAllDetail() { 
     mDatabase.delete(DetailTable.NAME, null, null); } 

und das ist mein FragmentOne:

public class FragmentOne extends Fragment { 
    private static final String SAVED_NUMBER_VISIBLE = "number"; 

    private RecyclerView mDetailRecyclerView; 
    private DetailAdapter mAdapter; 
    private boolean mNumberVisible; 
    private View view; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     view = inflater.inflate(R.layout.fragment_one_layout, 
       container, false); 

     mDetailRecyclerView = (RecyclerView) 
       view.findViewById(R.id.detail_recycler_view); 

     LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); 
     layoutManager.setReverseLayout(true); //This will reverse the data order but not scroll the RecyclerView to the last item 
     layoutManager.setStackFromEnd(true); //For keeping data order same and simply scrolling the RecyclerView to the last item 
     mDetailRecyclerView.setLayoutManager(layoutManager); 

     if (savedInstanceState != null) { 
      mNumberVisible = 
        savedInstanceState.getBoolean(SAVED_NUMBER_VISIBLE); 
     } 

     updateUI(); 
     return view; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     updateUI(); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putBoolean(SAVED_NUMBER_VISIBLE, mNumberVisible); 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     inflater.inflate(R.menu.fragment_one_layout, menu); 
     MenuItem numberItem = menu.findItem(R.id.show_numbers); 
     if (mNumberVisible) { 
      numberItem.setTitle(R.string.hide_numbers); 
     } else { 
      numberItem.setTitle(R.string.show_numbers); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 

      case R.id.show_numbers: 
       mNumberVisible = !mNumberVisible; 
       getActivity().invalidateOptionsMenu(); 
       updateNumbers(); 
       return true; 

      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 

    private void updateNumbers() { 
     DetailLab detailLab = DetailLab.get(getActivity()); 
     int detailCount = detailLab.getDetails().size(); 
     String number = getResources().getQuantityString 
       (R.plurals.number_plural, detailCount, detailCount); 


     if (!mNumberVisible) { 
      number = null; 
     } 

     AppCompatActivity activity = (AppCompatActivity) getActivity(); 
     activity.getSupportActionBar().setSubtitle(number); 
    } 

    private void updateUI() { 
     DetailLab detailLab = DetailLab.get(getActivity()); 
     List<Detail> details = detailLab.getDetails(); 
     if (details.size() == 0) { 
      TextView t = (TextView) view.findViewById(R.id.empty); 
      t.setText(R.string.empty_view); 
      t.setVisibility(View.VISIBLE); 
     } else { 
      TextView t = (TextView) view.findViewById(R.id.empty); 
      t.setVisibility(View.GONE); 
     } 

//   Toast.makeText(getContext(), "zero", Toast.LENGTH_SHORT).show(); 
     if (mAdapter == null) { 
      mAdapter = new DetailAdapter(details); 
      mDetailRecyclerView.setAdapter(mAdapter); 

     } else { 
      mAdapter.setDetails(details); 
      mAdapter.notifyDataSetChanged(); 
     } 

     updateNumbers(); 

    } 

    private class DetailHolder extends RecyclerView.ViewHolder 
      implements View.OnClickListener, View.OnLongClickListener { 
     private TextView mTitleTextView; 
     //  private TextView mDateTextView; 
     private Detail mDetail; 
     private RatingBar mRatingBar; 

     public DetailHolder(LayoutInflater inflater, ViewGroup parent) { 
      super(inflater.inflate(R.layout.list_item_detail, 
        parent, false)); 

      itemView.setOnClickListener(this); 
      itemView.setOnLongClickListener(this); 
      mTitleTextView = (TextView) itemView.findViewById(R.id.detail_title); 
//   mDateTextView = (TextView) itemView.findViewById(R.id.detail_date); 
      mRatingBar = (RatingBar) itemView.findViewById(R.id.ratingBar); 

     } 

     public void bind(Detail detail) { 
      mDetail = detail; 
      mTitleTextView.setText(mDetail.getTitle()); 
      mRatingBar.setRating(mDetail.getRate()); 
     } 

     @Override 
     public void onClick(View view) { 
      Intent intent = DetailPagerActivity.newIntent(getActivity(), 
        mDetail.getId()); 
      startActivity(intent); 
     } 

     @Override 
     public boolean onLongClick(View v) { 

      AlertDialog.Builder alert = new AlertDialog.Builder(
        getActivity()); 
      alert.setMessage(R.string.alert); 
      alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        DetailLab.get(getActivity()).deleteDetail(mDetail); 
        updateUI(); 
        updateNumbers(); 
        dialog.dismiss(); 
       } 
      }); 
      alert.setNegativeButton("No", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
       } 
      }); 
      alert.show(); 
      return true; 
     } 
    } 

    private class DetailAdapter extends RecyclerView.Adapter<DetailHolder> { 
     private List<Detail> mDetails; 

     public DetailAdapter(List<Detail> details) { 
      mDetails = details; 
     } 

     @Override 
     public DetailHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      LayoutInflater layoutInflater = 
        LayoutInflater.from(getActivity()); 

      return new DetailHolder(layoutInflater, parent); 
     } 

     @Override 
     public void onBindViewHolder(DetailHolder holder, int position) { 
      Detail detail = mDetails.get(position); 
      holder.bind(detail); 
     } 

     @Override 
     public int getItemCount() { 
      return mDetails.size(); 
     } 

     public void setDetails(List<Detail> details) { 
      mDetails = details; 
     } 
    } 
} 

und hier ist mein Layout für FragmentOne:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/fragment_one_layout"> 

    <android.support.v7.widget.CardView 
    android:id="@+id/card_view" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/detail_recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <TextView 
     android:id="@+id/empty" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:padding="50dp" 
     android:textAlignment="center" 
     android:textSize="20sp"/> 
</android.support.v7.widget.CardView> 

<android.support.design.widget.FloatingActionButton 
android:id="@+id/fab" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_alignParentBottom="true" 
android:layout_alignParentRight="true" 
android:layout_marginRight="24dp" 
android:layout_marginBottom="24dp" 
android:src="@drawable/ic_menu_add" 
android:scaleType="center" 
app:elevation="8dp" 
app:borderWidth="0dp" 
    /> 

mein logcat:

FATAL EXCEPTION: main 
Process: com.drgnme.listhamrah, PID: 23454 
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentTransaction android.support.v4.app.FragmentManager.beginTransaction()' on a null object reference 
at com.drgnme.listhamrah.MainActivity$1$1.onClick(MainActivity.java:76) 
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5451) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
+0

Sie fügen das Fragment erst nach dem Löschen der Aktivität hinzu. Auch Ihr Logcat zeigt eine Nullzeiger-Ausnahme in einer 'onClick()' Methode, die nicht mit der Aktualisierung des Fragments zusammenhängt. Allerdings gebe ich einen Weg, um eine Ui des Fragments in einer Antwort zu aktualisieren – leoOrion

Antwort

0

Ich denke, Sie dieses Problem haben, weil der Code unten in Ihrem MainActivity:

FragmentOne fragmentOne = new FragmentOne(); 
fragmentOne.getFragmentManager().beginTransaction().replace(R.id.card_view, fragmentOne).commit(); 

Sie versuchen, mit getFragmentManager() die Instanz des Fragments Manager zu erhalten, die Activity.getFragmentManager nennen, aber Ihre fragmentOne ist nicht an die Aktivität anhängen, so dass die Methode Null zurückgeben und Sie erhalten java.lang.NullPointerException

Anstelle von fragmentOne.getFragmentManager() verwenden Sie getSupportFragmentManager() direkt aus der Aktivität.

Hoffe, das hilft.

+0

ja ich tat es als @AyushKhare sagte und es funktionierte, tnx)) –

0

an ein Fragment des UI zu aktualisieren, um das Fragment-Manager verwenden, um das gleiche Abnehmen und Anbringen wieder fragmentieren.

ZB:

public void refreshFragmentUI(Fragment fragment) { 
     getSupportFragmentManager() 
      .beginTransaction() 
      .detach(fragment) 
      .attach(fragment) 
      .commit(); 
    } 

Hinweis: Verwenden Sie getSupportFragmentManager() wenn Sie Support-Bibliotheken verwenden. verwenden Else getFragmentManager()

1

Ich habe eine Methode namens updateUI in meinem FragmentOne aber wie könnte ich Zugriff auf diese Methode?

die updateUI Methode Ihres FragmentOne

alert_delete.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int which) { 

           DetailLab.get(getApplicationContext()).deleteAllDetail(); 

           Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem()); 
           // based on the current position you can then cast the page to the correct 
           // class and call the method: 
          if (ViewPager.getCurrentItem() == 0 && page != null) { 
           ((FragmentOne)page).updateUI();  
          } 

          dialog.dismiss(); 
          } 
         }); 
+0

Ja, es funktioniert für mich! aber nachdem ich die Zugriffsebene in meiner 'updateUI'-Methode von' private' auf 'protected' geändert habe; Vielen Dank!! –

0

Der beste Weg zu rufen Daten von SQLite-Datenbank in Fragmente zu aktualisieren LoaderManager.LoaderCallbacks und Adapter Cursor verwenden. Weil es ein asynchroner Prozess ist.

Verwandte Themen