2017-07-20 45 views
11

Mam problem z zakotwiczeniem FAB do widoku listy (See Video Example), wydaje się on migotać podczas rysowania, zmieniając pozycję zakotwiczenia. Problem pojawia się w emulatorze, a także na dowolnym urządzeniu Ja testowałem na poziomie API po 19.Zmienne zakotwiczenie przycisku akcji zmieniające się na tworzenie widoku

mam Główna działalność:

<LinearLayout 
    android:id="@+id/main_layout" 
    android:orientation="vertical" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".MainActivity"> 

    <!-- our toolbar --> 
    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="?attr/colorPrimary" 
     android:minHeight="?attr/actionBarSize" 
     android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
     app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
     android:elevation="4dp"/> 

    <!-- our tablayout to display tabs --> 
    <android.support.design.widget.TabLayout 
     android:id="@+id/tabLayout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="?attr/colorPrimary" 
     android:minHeight="?attr/actionBarSize" 
     android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
     android:elevation="4dp"/> 

    <!-- View pager to swipe views --> 
    <android.support.v4.view.ViewPager 
     android:id="@+id/pager" 
     android:layout_width="match_parent" 
     android:layout_height="fill_parent" /> 

</LinearLayout> 

Które następnie przytrzymuje dolny nav

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:background="#fff"> 

    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1" 
     android:id="@+id/svBody" 
     android:background="#fff"> 
    </FrameLayout> 
    <android.support.design.widget.BottomNavigationView 
     android:id="@+id/bottomNavigation" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom" 
     app:itemBackground="@color/colorPrimary" 
     android:background="@color/colorPrimary" 
     app:itemIconTint="@color/cardview_light_background" 
     app:itemTextColor="@color/cardview_light_background" 
     app:menu="@menu/bottom_navigation_main"> 
    </android.support.design.widget.BottomNavigationView> 
</LinearLayout> 

który posiada fragment:

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/lvWords" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 


    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:background="#fff"> 

     <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:orientation="horizontal" 
      android:background="#fff" 
      android:elevation="4dp"> 

     <TextView 
      android:text="Lipshapes" 
      android:layout_width="wrap_content" 
      android:layout_height="50dp" 
      android:id="@+id/lipshapes_titlestrip" 
      android:background="#33b5e5" 
      android:textColor="#fff" 
      android:textSize="32sp" 
      android:paddingTop="4dp" 
      android:paddingBottom="4dp" 
      android:elevation="6dp" 
      android:paddingLeft="@dimen/margin_medium" 
      android:paddingRight="@dimen/margin_medium"/> 

      <TextView 
       android:id="@+id/words_titlestrip" 
       android:layout_width="0dp" 
       android:layout_height="match_parent" 
       android:layout_gravity="bottom|right" 
       android:layout_weight="1" 
       android:background="#059FD8" 
       android:elevation="10dp" 
       android:paddingBottom="4dp" 
       android:paddingLeft="@dimen/margin_medium" 
       android:paddingRight="@dimen/margin_medium" 
       android:paddingTop="4dp" 
       android:text="Words" 
       android:textColor="#fff" 
       android:textSize="32sp" /> 

     </LinearLayout> 

     <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="0dp" 
     android:orientation="vertical" 
     android:layout_weight="1" 
     android:elevation="0dp" 
     android:background="#fff"> 


     <ListView 
     android:id="@android:id/list" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
      android:layout_weight="1" 
      /> 

     <View 
      android:id="@+id/view" 
      android:layout_width="match_parent" 
      android:layout_height="4dp" 
      android:background="@drawable/shadow" /> 

    </LinearLayout> 
    </LinearLayout> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/fab" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom|right" 
     android:layout_margin="16dp" 
     android:src="@drawable/plus_white_48" 
     app:layout_anchor="@android:id/list" 
     app:layout_anchorGravity="bottom|right|end" 
     app:fabSize="normal" /> 

I tu jest to, że fragmenty kodu:

public static class WordListSectionFragment extends ListFragment implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, View.OnClickListener, LoaderManager.LoaderCallbacks<Cursor> { 

     public SimpleCursorAdapter wordAdapter; 
     final static int LIST_VIEW = 0; 
     private FloatingActionButton fab; 
     String lipshape = null; 
     int lipshape_id = 0; 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_section_wordlist, container, false); 
      fab = (FloatingActionButton) rootView.findViewById(R.id.fab); 


      Bundle args = getArguments(); 

      lipshape = args.getString("lipshape_selected_desc"); 

      lipshape_id = Integer.valueOf(args.getString("lipshape_selected_id")); 

      ((TextView) rootView.findViewById(R.id.words_titlestrip)).setText(
        lipshape 
      ); 

      TextView lipshapesTV = (TextView) rootView.findViewById(R.id.lipshapes_titlestrip); 
      lipshapesTV.setOnClickListener(this); 


      return rootView; 
     } 

     @Override 
     public void onActivityCreated(Bundle savedInstanceState) { 
      super.onActivityCreated(savedInstanceState); 

      // if you only want one column do it like this 
      // String[] projection = new String[]{BaseColumns._ID, VideoFilesContract.videoFiles.FILENAME}; 
      wordAdapter = 
        new SimpleCursorAdapter(
          getContext(), 
          R.layout.item_word, 
          null, 
          new String[] {WordContract.wordItems.DESCRIPTION, "number_of_videos"}, 
          new int[] {R.id.tvWord, R.id.tvVideoCount}, 
          LIST_VIEW); 


      // Setup cursor adapter using cursor from last step 

      setListAdapter(wordAdapter); 
      //getListView().setOnItemClickListener(this); 

      getLoaderManager().initLoader(LIST_VIEW, null, this); 




     } 

     @Override 
     public void onViewCreated(View view, Bundle savedInstanceState) { 
      super.onViewCreated(view, savedInstanceState); 
      getListView().setOnItemClickListener(this); 
      getListView().setOnItemLongClickListener(this); 


      fab.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        // Click action 
        //Toast.makeText(getActivity(), "Button Clicked!", Toast.LENGTH_SHORT).show(); 

        Intent intent = new Intent(getActivity(), AddWord.class); 
        intent.putExtra("lipshape_selected_id", lipshape_id); 
        intent.putExtra("lipshape_selected_desc", lipshape); 


        startActivityForResult(intent, 1); 
       } 
      }); 
     } 

     public void restartLoader() 
     { 
      wordAdapter.swapCursor(null); 
      getLoaderManager().restartLoader(LIST_VIEW, null, this); 
     } 

     @Override 
     public void onActivityResult(int requestCode, int resultCode, Intent data) { 
      super.onActivityResult(requestCode, resultCode, data); 
      switch(requestCode) { 
       case (1) : { 
        if (resultCode == Activity.RESULT_OK) { 

         Boolean returnValue = data.getBooleanExtra("added_word", false); 

         if (returnValue) 
         { 
          restartLoader(); 
          Snackbar.make(getView().getRootView().findViewById(R.id.lvWords), "Word Added Successfully!", Snackbar.LENGTH_LONG) 
            .setAction("Action", null).show(); 
         } 
        } 
        break; 
       } 
      } 
     } 

     @Override 
     public void onClick(View v) 
     { 
      if (v.getId() == R.id.lipshapes_titlestrip) 
      { 
       LipshapeSectionFragment fragment = new LipshapeSectionFragment(); 

       FragmentManager fragmentManager = getFragmentManager(); 
       fragmentManager.beginTransaction().replace(R.id.svBody, fragment).commit(); 
      } 
     } 

     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int position,long id) 
     { 
      Cursor _cursor = ((Cursor) getListView().getItemAtPosition(position)); 
      Cursor cursor; 
      int count =0; 

      //do a count for videos if 0 

      int word_id = _cursor.getInt(_cursor.getColumnIndex("_id")); 
      String word = _cursor.getString(_cursor.getColumnIndex(WordContract.wordItems.DESCRIPTION)); 

      ContentResolver resolver = getContext().getContentResolver(); 

      if (word_id!=0) { 
       cursor = 
         resolver.query(VideoFilesContract.videoFiles.CONTENT_URI, 
           VideoFilesContract.videoFiles.PROJECTION_ALL, 
           "word_id=?", 
           new String[]{Integer.toString(word_id)}, 
           null, 
           null); 

       count = cursor.getCount(); 
      } 


      switch(count) 
      { 
       case 0: 

        Snackbar.make(view, "There are no videos recorded with this word.", Snackbar.LENGTH_LONG) 
          .setAction("Action", null).show(); 

        break; 
       default: 
        Intent intent = new Intent(getActivity(), CollectionDemoActivity.class); 
        intent.putExtra("word_id", word_id); 
        intent.putExtra("word", word); 
        startActivity(intent); 

      } 



      //Toast.makeText(getActivity(), "Item: " + test, Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public Loader<Cursor> onCreateLoader(int id, Bundle bundle) { 
      CursorLoader loader = null; 

      Bundle args = getArguments(); 



      switch (id) { 


       case LIST_VIEW: 
        loader = new CursorLoader(
          this.getActivity(), 
          WordContract.wordItems.CONTENT_TEST, 
          new String[]{WordContract.wordItems._ID, WordContract.wordItems.DESCRIPTION, "number_of_videos"}, 
          null, 
          new String[]{args.getString("lipshape_selected_id")}, 
          null); 

        return loader; 
       default: 
        return loader; 

      } 
     } 

      @Override 
      public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
      ((SimpleCursorAdapter)this.getListAdapter()). 
        swapCursor(cursor); 
     } 

      @Override 
      public void onLoaderReset(Loader<Cursor> loader) { 
      ((SimpleCursorAdapter)this.getListAdapter()). 
        swapCursor(null); 
     } 

     public void showDialog(final int word_id, String word_clicked) { 
      AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 
      builder.setTitle("Delete Word: "+ word_clicked + "?"); 
      builder.setMessage("Deleting this word will also delete all videos tagged by this word."); 


      String positiveText = "Delete"; 
      builder.setPositiveButton(positiveText, 
        new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 

          deleteWord(word_id); 
          //reload 

         } 
        }); 

      String negativeText = getString(android.R.string.cancel); 
      builder.setNegativeButton(negativeText, 
        new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          // negative button logic 
         } 
        }); 

      AlertDialog dialog = builder.create(); 
      // display dialog 
      dialog.show(); 
     } 

     public boolean deleteWord(int word_id) 
     { 
      ContentResolver resolver = getContext().getContentResolver(); 

      Uri delUri = ContentUris.withAppendedId(WordContract.wordItems.CONTENT_URI, word_id); 

      //resolver.delete(VideoFilesContract.videoFiles.CONTENT_URI, "_id=?", selectionArgs); 

      long resultCount = resolver.delete(delUri, null, null); 

      if (resultCount == 0) 
      { 
       //couldn't delete word with that id 
       return false; 
      } 
      else 
      { 
       restartLoader(); 
       Snackbar.make(getListView(), "Word deleted successfully.", Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 
       return true; 
      } 
     } 

     @Override 
     public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) 
     { 

      //Snackbar.make(view, "Item has been long clicked!", Snackbar.LENGTH_LONG) 
       //  .setAction("Action", null).show(); 
      Cursor _cursor = ((Cursor) getListView().getItemAtPosition(i)); 
      Cursor cursor; 
      int count =0; 

      //do a count for videos if 0 

      int word_id = _cursor.getInt(_cursor.getColumnIndex("_id")); 
      String word = _cursor.getString(_cursor.getColumnIndex(WordContract.wordItems.DESCRIPTION)); 

      showDialog(word_id, word); 

      return true; 
     } 
    } 

Odpowiedz

7

nie mogłem znaleźć czystsze poprawkę niż ustawienie widoczności Fab do gone początkowo, ale ustawienie kotwicę do ListView:

<android.support.design.widget.FloatingActionButton 
     android:id="@+id/fab" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom|right|end" 
     android:layout_margin="16dp" 
     android:src="@drawable/plus_white_48" 
     android:visibility="gone" 
     app:layout_anchor="@android:id/list" 
     app:layout_anchorGravity="bottom|right|end" 
     app:fabSize="normal" /> 

I wtedy, gdy lista nie jest pusta po kursor zakończeniu ładowania po prostu sprawiają, że widoczne i to zakotwicza jak powyżej, a w przypadkach, gdy Lis jest pusta, możemy ustawić params układu zakotwiczyć na pustej listy:

if (wordAdapter.getCursor().getCount()<1) 
{ 
//the linear layout for the empty list view state 
       ll.setVisibility(View.VISIBLE); 
//set the text of this to be visible too, default is invisible as otherwise it's visible when the list is loading 
       tvFeedback.setVisibility(View.VISIBLE); 

       CoordinatorLayout.LayoutParams p (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); 
       p.setAnchorId(R.id.empty_list_view); 
       fab.setLayoutParams(p); 
       fab.setVisibility(View.VISIBLE); 

} 

powoduje bez migotania podczas ładowania, a także prowadzi do kotwicy zawsze będąc przy współpracy popraw miejsce nawet, gdy elementy z listy zostaną usunięte.

1

Widzisz fab w lewym górnym rogu, ponieważ w tym momencie ListView nie są określone na ListView. Po zapełnieniu pozycji, ListView dopasowuje swój obiekt nadrzędny, a FAB jest umieszczony prawidłowo.

Dołącz kotwicę FAB do rodzica, który już pasuje do całej przestrzeni i przechowuje twój ListView.

coś takiego

<LinearLayout 
    **android:id="@+id/list_parent"** 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:background="#fff"> 

    <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="50dp" 
    android:orientation="horizontal" 
     android:background="#fff" 
     android:elevation="4dp"> 

    <TextView 
     android:text="Lipshapes" 
     android:layout_width="wrap_content" 
     android:layout_height="50dp" 
     android:id="@+id/lipshapes_titlestrip" 
     android:background="#33b5e5" 
     android:textColor="#fff" 
     android:textSize="32sp" 
     android:paddingTop="4dp" 
     android:paddingBottom="4dp" 
     android:elevation="6dp" 
     android:paddingLeft="@dimen/margin_medium" 
     android:paddingRight="@dimen/margin_medium"/> 

     <TextView 
      android:id="@+id/words_titlestrip" 
      android:layout_width="0dp" 
      android:layout_height="match_parent" 
      android:layout_gravity="bottom|right" 
      android:layout_weight="1" 
      android:background="#059FD8" 
      android:elevation="10dp" 
      android:paddingBottom="4dp" 
      android:paddingLeft="@dimen/margin_medium" 
      android:paddingRight="@dimen/margin_medium" 
      android:paddingTop="4dp" 
      android:text="Words" 
      android:textColor="#fff" 
      android:textSize="32sp" /> 

    </LinearLayout> 

    <LinearLayout 
    android:layout_width="wrap_content" 
    android:layout_height="0dp" 
    android:orientation="vertical" 
    android:layout_weight="1" 
    android:elevation="0dp" 
    android:background="#fff"> 


    <ListView 
    android:id="@android:id/list" 
    android:layout_width="match_parent" 
    android:layout_height="0dp" 
     android:layout_weight="1" 
     /> 

    <View 
     android:id="@+id/view" 
     android:layout_width="match_parent" 
     android:layout_height="4dp" 
     android:background="@drawable/shadow" /> 

</LinearLayout> 
</LinearLayout> 

<android.support.design.widget.FloatingActionButton 
    android:id="@+id/fab" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="bottom|right" 
    android:layout_margin="16dp" 
    android:src="@drawable/plus_white_48" 
    app:layout_anchor="@+id/list_parent" 
    app:layout_anchorGravity="bottom|right|end" 
    app:fabSize="normal" /> 

Friendly końcówki, przełącznik do RecyclerView.

+0

Wydaje się, że powoduje to te same problemy, jak sądzę, ponieważ po pierwszym wymianie fragmentu nowy widok nadal znajduje się na wysokości "0". – benjgorman