Pude resolver este problema usando el oyente de desplazamiento en la vista de lista. (probado en 2.1)
Digamos que para cada fila de lista tengo un diseño como el siguiente. Hay una parte de contenido y una parte de encabezado. No importa qué tipo de vista use para encabezado o contenido.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:background="#FFFFFF">
<ImageView
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="@drawable/pic"
android:background="#aaaaff"
android:layout_marginTop="40dp"/>
<TextView
android:id="@+id/header"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:padding="12dp"
android:text="Deneme Row"
android:textColor="#000000"
android:background="#99ffffff"/>
</RelativeLayout>
La disposición de ensayo para la actividad es como en el siguiente:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
Finalmente el código de la actividad es la siguiente. Aquí tuve que tener un adaptador que utiliza ViewHolder para almacenar la vista de encabezado y también una variable para realizar un seguimiento del cambio en el desplazamiento para cada evento de desplazamiento sucesivo (previousTop). Esto se debe al hecho de que offsetTopAndBottom() cambia el desplazamiento de la vista relacionada con la ubicación anterior de la misma.
public class TestActivity extends Activity implements AbsListView.OnScrollListener{
ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list = (ListView) findViewById(R.id.list);
list.setAdapter(new Adapter(this));
list.setOnScrollListener(this);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//the listview has only few children (of course according to the height of each child) who are visible
for(int i=0; i < list.getChildCount(); i++){
View child = list.getChildAt(i);
ViewHolder holder = (ViewHolder) child.getTag();
//if the view is the first item at the top we will do some processing
if(i == 0){
boolean isAtBottom = child.getHeight() <= holder.header.getBottom();
int offset = holder.previousTop - child.getTop();
if(!(isAtBottom && offset > 0)){
holder.previousTop = child.getTop();
holder.header.offsetTopAndBottom(offset);
holder.header.invalidate();
}
} //if the view is not the first item it "may" need some correction because of view re-use
else if (holder.header.getTop() != 0) {
int offset = -1 * holder.header.getTop();
holder.header.offsetTopAndBottom(offset);
holder.previousTop = 0;
holder.header.invalidate();
}
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
private static class Adapter extends ArrayAdapter<String> {
public Adapter(Context context) {
super(context, R.layout.row, R.id.header);
for(int i=0; i < 50; i++){
add(Integer.toString(i));
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, parent, false);
ViewHolder holder = new ViewHolder();
holder.header = (TextView) convertView.findViewById(R.id.header);
convertView.setTag(holder);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.header.setText(getItem(position));
return convertView;
}
}
private static class ViewHolder {
TextView header;
int previousTop = 0;
}
}
Hey siyamed, Esto es muy útil. En mi caso, tengo un ListView (hijo) más dentro de ListView (Parent). entonces el encabezado no funciona correctamente cuando estoy desplazándome hacia abajo ... – ashish2py
Si no hay datos en child-listview, entonces funciona correctamente ... > aplicación de ejemplo https://bitbucket.org/ashish2py/instagramheader – ashish2py
Lo intentaré. ¡Gracias! –