2016-06-18 5 views
2

В моей деятельности у меня есть карта с маркерами. Когда пользователь нажимает маркер, он показывает подробности об этом месте с нижним листом.андроид - нижнее поведение поведение детей изменения не всегда работают

Когда представления, заполненные данными о месте в первый раз, работают правильно. Но после скрытия нижнего листа, а затем показывая его после щелчка, он не работает должным образом: TextView сохраняет старую высоту (view.invalidate() не работает). viewGroup.addView метод не работает (вызов viewGroup.removeAllViews() перед добавлением, но он сохраняет старую высоту и добавление просмотров не работает).

Но когда я изменяю данные представления, не скрывая/показывая bottomSheet, все работает нормально. Как изменение в первый раз.

Я также видел другие другие странные поведения, в то время как отладка: у меня был linearLayout, у которого было 4 relativeLayouts (с textView и imageView внутри). Когда я изменил видимость (ушел/увидел) один/два, они бы перекрывались друг с другом, хотя linearLayout имел вертикальную ориентацию. Но не всегда, так же, как и выше: первый раз работает нормально, в других случаях, если я изменяю виды, когда bottomSheet не отображается, не работает должным образом (как описано), но когда bottomBehavior видимо, и если я меняю виды, он работает нормально (например, сначала время).

Если я не ошибаюсь, это из-за нижнего предела. Becuause, я не видел подобного поведения взглядов на Android раньше.

Мой код:

mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView); 
    mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 
     @Override 
     public void onStateChanged(@NonNull View bottomSheet, int newState) { 
      switch (newState) { 
       case BottomSheetBehavior.STATE_HIDDEN: 
        hidePlaceDetails(); 
        break; 
      } 
     } 

     @Override 
     public void onSlide(@NonNull View bottomSheet, float slideOffset) { 
     } 
    }); 

/** 
* Show bottom sheet with given place details and start load route 
* 
* @param place the place 
*/ 
private void showPlaceDetails(Place place) { 
    placeTitleView.setText(place.getTitle()); 
    placeCategoryView.setText(place.getParentTitle()); 

    placeInfoGroup.removeAllViews(); 
    addPlaceInfo(R.drawable.ic_info, place.getDescription(), null); 
    addPlaceInfo(R.drawable.ic_place, place.getAddress(), null); 
    addPlaceInfo(R.drawable.ic_phone, place.getPhoneNumbers(), null); 
    addPlaceInfo(R.drawable.ic_language, place.getWebsite(), null); 

    Photo photo = place.getPhoto(); 
    if (U.isEmpty(photo.getImagePath())) { 
     U.hideView(placePhotoView); 
    } else { 
     U.showView(placePhotoView); 
     int proportionalHeight = U.calculateProportionalHeight(
      screenSize[0] /*screenWidth*/, 
      photo.getWidth(), 
      photo.getHeight(), 
      800 /*maxHeight*/); 
     FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
      ViewGroup.LayoutParams.MATCH_PARENT, 
      proportionalHeight 
     ); 

     placePhotoView.setLayoutParams(layoutParams); 
     ImageUtils.networkImage(this, photo, placePhotoView, null, U.imagePlaceholder()); 
    } 

    U.view(placeDistanceProgressView, true); //showView 
    U.view(placeDistanceView, false); //hideView 
    if (mMap.getMyLocation() != null) { 
     Waypoint myLocation = new Waypoint(mMap.getMyLocation().getLongitude(), mMap.getMyLocation().getLatitude()); 
     Waypoint destination = new Waypoint(place.getPosition().getLongitude(), place.getPosition().getLatitude()); 

     getAndDrawRoute(place, myLocation, destination); 
    } 

    int thirdScreen = screenSize[1]/3; 
    mMap.setPadding(0, 0, 0, halfScreen); 
    isShowingPlaceDetails = true; 
    mBottomSheetBehavior.setPeekHeight(halfScreen); 
    mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 
} 

/** 
* Hide bottom sheet and add markers 
*/ 
private void hidePlaceDetails() { 
    mMap.setPadding(0, 0, 0, 0); 
    mBottomSheetBehavior.setPeekHeight(0); 
    mBottomSheetBehavior.setHideable(true); 
    mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 
    addMarkers(); 
    isShowingPlaceDetails = false; 
} 

/** 
* @param icon   icon res 
* @param title   title 
* @param onClickListener nullable 
*/ 
private void addPlaceInfo(
    @DrawableRes int icon, String title, @Nullable View.OnClickListener onClickListener) { 
    View root = LayoutInflater.from(this).inflate(R.layout.layout_map_bottom_sheet_row, null); 
    ImageView iconView = ButterKnife.findById(root, R.id.place_icon); 
    TextView titleView = ButterKnife.findById(root, R.id.place_title); 
    iconView.setImageResource(icon); 
    titleView.setText(U.notEmpty(title) ? title : Html.fromHtml(String.format("<i>%s</i>", "None"))); 

    if (onClickListener != null) { 
     root.setOnClickListener(onClickListener); 
    } 
    placeInfoGroup.addView(root); 
} 

активность * .xml

<android.support.v4.widget.DrawerLayout 
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:id="@+id/drawer" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:fitsSystemWindows="true"> 

<android.support.design.widget.CoordinatorLayout 
    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:orientation="vertical"> 

    <include layout="@layout/toolbar_appbar"/> 

    <RelativeLayout 
     android:id="@+id/content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

     ... 
    </RelativeLayout> 

    <android.support.v4.widget.NestedScrollView 
     android:id="@+id/bottomSheet" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:background="@android:color/white" 
     android:elevation="4dp" 
     app:behavior_peekHeight="0dp" 
     app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> 

     <include layout="@layout/layout_map_bottom_sheet"/> 

    </android.support.v4.widget.NestedScrollView> 

</android.support.design.widget.CoordinatorLayout> 

... 

layout_map_bottom_sheet.xml

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@android:color/white" 
android:orientation="vertical" 
android:paddingTop="@dimen/content.margin"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:paddingLeft="@dimen/content.padding.big" 
    android:paddingStart="@dimen/content.padding.big" 
    android:paddingRight="@dimen/content.padding" 
    android:paddingEnd="@dimen/content.padding"> 

    <TextView 
     android:id="@+id/place.title" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:lineSpacingExtra="@dimen/text.line.space" 
     android:textColor="@color/text.color" 
     android:textSize="@dimen/text.xlarge" 
     tools:text="@string/lorem.place.title"/> 

    <TextView 
     android:id="@+id/place.category" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:lineSpacingExtra="@dimen/text.line.space" 
     android:paddingBottom="@dimen/content.padding.small" 
     android:paddingTop="@dimen/content.padding.small" 
     android:textSize="@dimen/text.medium" 
     android:textColor="@color/text.secondary.color" 
     tools:text="@string/lorem.short"/> 

    <include layout="@layout/divider"/> 

    <TextView 
     android:id="@+id/place.distance" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:paddingBottom="@dimen/content.padding.small" 
     android:paddingTop="@dimen/content.padding.small" 
     android:textColor="?attr/colorPrimary" 
     android:visibility="gone" 
     tools:text="@string/lorem.place.distance"/> 

    <ProgressBar 
     android:id="@+id/place.distance.progress" 
     android:layout_width="20dp" 
     android:layout_height="20dp" 
     android:layout_marginTop="@dimen/content.padding.small" 
     android:layout_marginBottom="@dimen/content.padding.small"/> 

    <include layout="@layout/divider"/> 
</LinearLayout> 

<LinearLayout 
    android:id="@+id/place.infos" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 
</LinearLayout> 

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <ImageView 
     android:id="@+id/place.photo" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:scaleType="centerCrop" 
     tools:src="@drawable/sample"/> 
</FrameLayout> 

Screenrecord: https://drive.google.com/file/d/0B5up2CgQawSDbUZtQ2h1VDBWbms/view?usp=drivesdk

Мне было сложно объяснить это, но этот вопрос заставил меня с ума сойти на пару дней. Я очень ценю любую помощь, которую вы можете предоставить!

+0

ли вы решить эту проблему? Кажется, у меня такая же или очень похожая проблема. Это происходит, когда я использую removeAllViews. Если я не использую removeAllViews, то он работает. – peshkira

+0

@peshkira nope. Я отказался от – alashow

+0

oh, noes:/... Кажется, это проблема жизненного цикла макета с нижним листом, потому что отладчик говорит, что представления вставляются для меня. Но я их не вижу. – peshkira

ответ

1

Я решил аналогичную проблему со следующим обходным решением.

В моих BottomSheetCallback я добавил следующее:

behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 
    @Override 
    public void onStateChanged(final View bottomSheet, int newState) { 
    switch (newState) { 
     case BottomSheetBehavior.STATE_COLLAPSED: 
     case BottomSheetBehavior.STATE_EXPANDED: 
     bottomSheet.post(new Runnable() { 
      @Override 
      public void run() { 
      bottomSheet.requestLayout(); // this seems to fix it. 
      } 
     }); 
     break; 
     case BottomSheetBehavior.STATE_HIDDEN: 
     // remove the views here with removeAllViews(); 
     break; 
    } 
    } 

    @Override 
    public void onSlide(View bottomSheet, float slideOffset) { 

    } 
}); 

Это еще не совершенно, потому что новый макет занимает некоторое время, чтобы сделать и взгляды поп с некоторой задержкой. Но лучше, чем ничего.

Кроме того, там, кажется, устранение ошибки, для этого в течение последней поддержки Lib 24.0.0, если вы уже поддерживаете цель на 24

https://code.google.com/p/android/issues/detail?id=205226

+0

Я попробовал недействительный макет. Но это не сработало. Но я не пытался сделать недействительным при расширении состояния с пост-запуском. Я изменил структуру макета, поэтому не могу проверить, работает ли ваше решение. Я буду принимать его в качестве решения, если другие пользователи проголосуют за ваше решение. Благодаря! – alashow

+0

отлично. Обратите внимание, что 'invalidate' не совпадает с' requestLayout'. Invalidate только маркирует макет как грязный, тогда как requestLayout планирует новый макет. – peshkira

 Смежные вопросы

  • Нет связанных вопросов^_^