Charlie-Blake
Charlie-Blake

Reputation: 11050

3 way scroll in Android

I have 3 views: an ImageView, a RelativeLayout and a ListView. When the user scrolls down, I have to hide the ImageView first. When the top of the RelativeLayout touches the top of the screen it has to fix itself there and the scroll must be done by the ListView. Then when I scroll up, the top of the ListView must be visible before the ImageView starts to scroll down again.

Is there any component that does what I want without having to write my own component?

(Just to make things easier, it should work like the headers in Instagram, when the header reaches the top it stays there, but there should be only one header)

Upvotes: 0

Views: 77

Answers (1)

Lamorak
Lamorak

Reputation: 11137

I have a very simple solution to this, hope it helps. I use one header added to the listView and the same header added to the page on top. There is a listener to toggle visibility of the fixed header. Everything is done in the onCreate method:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ListView listView = (ListView) findViewById(R.id.list);

    LayoutInflater inflater = getLayoutInflater();
    // your image header
    View headerImage = inflater.inflate(R.layout.header_image, listView, false);
    listView.addHeaderView(headerImage);
    // the header that scrolls with the listview
    final View fixedHeader = inflater.inflate(R.layout.header_fixed, listView, false);
    listView.addHeaderView(fixedHeader);

    // the header that is fixed on top of the screen
    final View secondFixedHeader = findViewById(R.id.fixed_header);
    secondFixedHeader.setVisibility(View.GONE);

    listView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {}

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (firstVisibleItem > 0) {
                secondFixedHeader.setVisibility(View.VISIBLE);
            } else {
                secondFixedHeader.setVisibility(View.GONE);
            }
        }
    });

    listView.setAdapter(new ListAdapter(this));
}

there is the activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <include
        android:id="@+id/fixed_header"
        layout="@layout/header_fixed" />

</RelativeLayout>

there is the header_fixed.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:background="@android:color/darker_gray">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is a fixed header"
        android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"/>

</RelativeLayout>

and there is the header_image.xml:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/android"/>

Upvotes: 1

Related Questions