Fare un elemento centrale per bloccarsi nell'intestazione (ScrollView / ListView)

Voglio fare un elemento che viene visualizzato al centro di ScrollView (o ListView ) al primo posto e poi si blocca nell'intestazione dello schermo quando viene scorciato.

È un'implementazione prototipo in CSS + JS: http://jsfiddle.net/minhee/aPcv4/embedded/result/ .

  • notifyDataSetChanged () rende l'elenco aggiornato e scorrimento salti di nuovo alla parte superiore
  • Come risolvere i problemi di java.lang.OutOfMemoryError in Android
  • Testo a voce (TTS) -Android
  • Come gonfiare la vista da XML in Android?
  • ImageView senza definizione xml
  • Il test di scimmia Android sceglie un'attività specifica
  • A prima vista farò ScrollView per includere ListView , ma i documenti ufficiali dicono:

    Non utilizzare mai uno ScrollView con un ListView, perché ListView si occupa della sua scorrimento verticale. La cosa più importnte, facendo questo, sconfigge tutte le ottimizzazioni importnti di ListView per la gestione di elenchi di grandi size, perché effettivamente costringe il ListView a visualizzare l'intera list di elementi per riempire il contenitore infinito fornito da ScrollView.

    Quindi, quali approcci posso cercare di raggiungere questo UI?

    Aggiornamento : Ho provato StickyListHeaders , ma: "Attualmente non è ansible avere elementi interattivi nell'intestazione, pulsanti, interruttori, ecc funziona solo quando l'intestazione non è bloccata". Inoltre, ritengo che non sia molto adatto a questa situazione . Non ho bisogno di più intestazioni, ma solo un elemento centrale per bloccarsi nell'intestazione.

  • come programmare un'esecuzione di codice in android o quali sono i thread daemon in android?
  • Google mappa che mostra solo piastrelle vuote android
  • Contare per 45 secondi, mettere in pausa per 20 poi ripetere con un titolo diverso
  • Invio di email da app android
  • Bug di browser Android? scorrimento overflow div
  • TrafficStats Api android e calcolo dell'utilizzo quotidiano dei dati
  • 3 Solutions collect form web for “Fare un elemento centrale per bloccarsi nell'intestazione (ScrollView / ListView)”

    Ho usato (o meglio, ho provato ad usare) la libreria di StickyListHeaders in passato. Dopo aver avuto qualche problema con esso, ho scoperto quanto segue. Non è molto diverso da quello che altri manifesti hanno suggerito.

    Il file di layout principale di activity_layout.xml costituito da un ListView e da un LinearLayout invisibile per impostazione predefinita. Utilizzando il metodo onScroll () di LinearLayout's visibilità LinearLayout's viene triggersta. Non è necessario gonfiare un altro layout o aggiungere viste dynamicmente al genitore del layout. Questo è ciò che sembra il metodo onScroll :

     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem > 3) { // 5th row will stick llHeader.setVisibility(View.VISIBLE); } else { llHeader.setVisibility(View.GONE); } } 

    Semplicemente, cambiate la visibilità per get l'effetto desiderato. Puoi dare un'occhiata al seguente codice. Il suo esempio di lavoro di quello che si può aspettare. L'attività contiene un ListView con estensione strettamente barebone di BaseAdapter . Il ListView è popolato con pulsanti numerati (uno su ciascuna row, a partire da 0, e salendo fino a 19).

     public class StickyHeader extends Activity { LinearLayout llHeader; ListView lv; SHAdapter shAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout); lv = (ListView) findViewById(R.id.listView1); llHeader = (LinearLayout) findViewById(R.id.llHeader); shAdapter = new SHAdapter(); lv.setAdapter(shAdapter); lv.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) {} @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem > 3) { llHeader.setVisibility(View.VISIBLE); } else { llHeader.setVisibility(View.GONE); } } }); } public class SHAdapter extends BaseAdapter { Button btCurrent; int[] arr = new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; @Override public int getCount() { return 20; } @Override public Object getItem(int arg0) { return arr[arg0]; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = getLayoutInflater().inflate(R.layout.list_item_layout, null); btCurrent = (Button) convertView.findViewById(R.id.button1); if ((Integer)getItem(position) == 4) { btCurrent.setText("Number " + getItem(position) + " is sticky"); } else { btCurrent.setText("" + getItem(position)); } return convertView; } } } 

    activity_layout.xml

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> <!-- This LinearLayout's visibility is toggled --> <!-- Improvement suggested by user 'ar34z' (see comment section below) --> <include layout="@layout/list_item_layout" /> </RelativeLayout> 

    list_item_layout

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llHeader" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/white" android:orientation="vertical" > <Button android:id="@+id/button1" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 

    Questo è il codice più semplice per illustrare l'idea principale:

     listView.setOnScrollListener(new OnScrollListener() { ViewGroup mainView = (ViewGroup) findViewById(R.id.main); View pinnedView = null; @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem < PINNED_ITEM) { mainView.removeView(pinnedView); pinnedView = null; } else if (pinnedView == null) { pinnedView = adapter.getView(PINNED_ITEM, null, view); pinnedView.setBackgroundColor(0xFF000000); mainView.addView(pinnedView); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) {} }); 

    Ho un FrameLayout che non contiene niente ma il mio ListView :

     <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main" > <ListView android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> 

    PINNED_ITEM è la posizione del tuo elemento (ad esempio, PINNED_ITEM = 2 ). Questo layout funge da overlay per l'elenco. Lo ScrollListener traccia gli elementi visibili attuali e se rileva che un elemento deve essere pinzato, lo aggiunge al layout e la rimuove altrimenti.

    La row pinnedView.setBackgroundColor(0xFF000000); è necessario per impostare uno background opaco per l'elemento. L'articolo sarà trasparente se non lo fai. È ansible modificare lo background in base alle proprie esigenze (ad esempio, è ansible utilizzare uno background dell'attuale attributo di tema).

    Per realizzarlo, metterò la listView in un relativeLayout e aggiungere un listener sullo scroll. Poi in esso, quando cambia il firstVisibleItem, duplicerò l'itemView che ti serve e visualizzerai sopra il tuo listView.

    Ecco un breve esempio di quello che penso. Le uniche cose è che la vista duplicata deve essere opaca.

     import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RelativeLayout; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /*Create listView inside a relativelayout*/ final RelativeLayout rl = new RelativeLayout(this); final ListView lv = new ListView(this); rl.addView(lv); /* Set it as a content view*/ setContentView(rl); /*populate it*/ String[] items = { "Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean"}; int size = 10; String[] arraysItems = new String[items.length*size]; for(int i = 0; i < arraysItems.length; i++) arraysItems[i] = items[i%items.length] + " " + i; /* Need to use a non transparent view*/ final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.simple_list_item_1_opaque, arraysItems); lv.setAdapter(adapter); /* Choose the item to stick*/ final int itemToStick = 3; /* Create things needed for duplication */ final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); final RelativeLayout.LayoutParams selectorParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, lv.getDividerHeight()); lv.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if(itemToStick <= firstVisibleItem && rl.getChildCount() == 1) { /* Put view in a linearlayout in order to be able to add the sepline */ LinearLayout ll = new LinearLayout(view.getContext()); ll.setOrientation(LinearLayout.VERTICAL); ll.addView(adapter.getView(itemToStick, null, null),params); /* Create Divider */ View selector = new LinearLayout(view.getContext()); selector.setBackground(lv.getDivider()); /* add views*/ ll.addView(selector,selectorParams); rl.addView(ll,params); } /* Remove view when scrolling up to it */ else if(itemToStick > firstVisibleItem) { if(rl.getChildCount() > 1) rl.removeViewAt(1); } } }); } } 

    E semplice_list_item_1_opaque:

     <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:minHeight="?android:attr/listPreferredItemHeightSmall" android:background="#FFFFFF" /> 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.