2015-05-23 17 views
1

Я хочу сделать что-то вроде sticky menu, но я не имею ни малейшего понятия об этом. Мой XML-то вроде этого:Исправить элемент на ScrollView

<com.example.customscrollview.scrollview 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 
    <FrameLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical"> 
     <!-- I need sticky this element bellow! --> 
     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="210.0dip" 
      android:orientation="vertical"> 
     </LinearLayout> 
     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" 
      android:layout_marginTop="210.0dip"> 
      <!-- A lot of TextViews --> 
      <TextView...> 
      <TextView...> 
      <TextView...> 
     </LinearLayout> 
    </FrameLayout> 
</com.example.customscrollview.scrollview> 

Я пытался сделать это программно:

private void setTouchListeners() { 
    setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      boolean rt = false; 
      if (event.getAction() == MotionEvent.ACTION_MOVE) { 
       final View element = (View) findViewById(R.id.element); 
       LayoutParams params = new LayoutParams(
         LayoutParams.MATCH_PARENT, 
         element.getHeight() 
       ); 
       params.setMargins(0, (int) getScrollY(), 0, 0); 
       params.gravity = Gravity.TOP; 
       element.setLayoutParams(params); 
       Handler handler = new Handler(); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         childElement.requestLayout(); 
        } 
       }); 
      } 
      return rt; 
     } 
    }); 
} 

Это работает, но не идеально. Когда ScrollView начнет бросать, движение не будет завершено, потому что MotionEvent связывает только события касания. Поэтому я перезаписываю onScrollChanged для выполнения той же функции (с некоторыми изменениями). Хорошо, теперь элемент остается в верхней части, но он не следует движению прокрутки, он становится «неустойчивым» до тех пор, пока прокрутка не остановится (результат отбрасывания и быстрой скорости прокрутки).

Каков наилучший способ сделать это?

+0

вы можете остановиться, когда вы говорите _ _ – Elltz

+0

@Elltz, я редактировал вопрос со ссылкой на то, что я хочу достичь, здесь: http://codepen.io/Guilh/pen/JLKbn. * * - это просто указать, кто является элементом. –

ответ

2

Вы можете легко найти его, изменив гнездование. Если вы создадите корневой элемент FrameLayout, вы можете плавать надпись поверх ScrollView. Цена, которую вы платите, состоит в том, что она отображается в макете дважды. Если не слишком много просмотров, это, вероятно, стоит заплатить.

Вам необходимо программное управление для изменения visibility липкой навигации, когда прокрутка навигации попадает в верхнюю часть представления. Вам не нужен программный контроль, чтобы сохранить липкую навигацию.

<!-- FrameLayout simply positions all its children at the requested height, width, 
    gravity and margins. It doesn't try to avoid child views overlapping each 
    other. The items are rendered in top-to-bottom XML order. --> 
<FrameLayout layout_width="match_parent" 
      layout_height="match_parent"> 

    <!-- The scrollable main content. --> 
    <ScrollView layout_width="match_parent" 
       layout_height="match_parent"> 
     <LinearLayout layout_width="match_parent" 
         layout_height="wrap_content" 
         orientation="vertical"> 

      <!-- The scrolling version of the navigation section --> 
      <LinearLayout layout_width="match_parent" 
          layout_height="wrap_content" 
          orientation="horizontal"> 
       <!-- menu items go here --> 
      </LinearLayout> 

      <!-- content views go here. Note: if you're doing data binding to 
       populate this, consider RecyclerView instead of ScrollView. --> 
      <TextView /> 
      <TextView /> 

     </LinearLayout> 
    </ScrollView> 

    <!-- This is a copy of the navigation section. --> 
    <LinearLayout layout_width="match_parent" 
        layout_height="wrap_content" 
        layout_gravity="top" 
        visibility="invisible" 
        orientation="horizontal"> 
     <!-- menu items go here --> 
    </LinearLayout> 
</FrameLayout> 

(я ушел из android: префиксы для примера Вам понадобятся.).

+0

Отлично! У меня есть «заголовок» в корневой FrameLayout, когда невидимый LinearLayout становится видимым, он перекрывает заголовок. Есть ли способ, чтобы заголовок перекрывал LinearLayout, не отправляя его в нижней части XML? –

+0

Если вы дадите заголовку фиксированный layout_height в 'dp' вместо того, чтобы сделать его wrap_content, тогда вы можете поместить ту же высоту, что и layout_marginTop в разделе меню. – Barend

+0

Да, я сделал это. Огромное спасибо :) –

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