In this post, I would like to introduce a powerful external libary to make this effect, called Android-ObservableScrollView. With it, we can auto show/hide ActionBar quite easily and smoothly, please see this DEMO VIDEO first:
Import libary
compile 'com.github.ksoichiro:android-observablescrollview:1.6.0'
Declaring layouts
Programmatically Code
@Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { ActionBar ab = getSupportActionBar(); if (ab == null) { return; } if (scrollState == ScrollState.UP) { if (ab.isShowing()) { ab.hide(); } } else if (scrollState == ScrollState.DOWN) { if (!ab.isShowing()) { ab.show(); } } }In activity which contain a ListView, I read a text file from Assets and save strings to ArrayList to make it's data. Full code for this activity is below (onDownMotionEvent(), onScrollChanged() are also belong to ObservableScrollViewCallbacks interface):
package devexchanges.info.autohideactionbar; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.widget.AbsListView; import android.widget.ArrayAdapter; import com.github.ksoichiro.android.observablescrollview.ObservableListView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ScrollState; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; public class ListViewActivity extends AppCompatActivity implements ObservableScrollViewCallbacks { private ObservableListView listView; private ArrayList<String> friends; private ArrayAdapter<String> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); friends = new ArrayList<>(); listView = (ObservableListView) findViewById(R.id.list); listView.setScrollViewCallbacks(this); readAssets(); setListViewAdapter(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } private void readAssets() { BufferedReader reader = null; try { reader = new BufferedReader( new InputStreamReader(getAssets().open("friendslist.txt"), "UTF-8")); // do reading, usually loop until end of file reading String mLine = reader.readLine(); while (mLine != null) { mLine = reader.readLine(); friends.add(mLine); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } private void setListViewAdapter() { adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, friends); listView.setAdapter(adapter); } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { ActionBar ab = getSupportActionBar(); if (ab == null) { return; } if (scrollState == ScrollState.UP) { if (ab.isShowing()) { ab.hide(); } } else if (scrollState == ScrollState.DOWN) { if (!ab.isShowing()) { ab.show(); } } } }After running, this screen will be like this output:
With similar steps above, we create a activity with a ScrollView with this effect:
package devexchanges.info.autohideactionbar; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ScrollState; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ScrollViewActivity extends AppCompatActivity implements ObservableScrollViewCallbacks { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scroll); ObservableScrollView scrollView = (ObservableScrollView) findViewById(R.id.scroll); textView = (TextView)findViewById(R.id.text); scrollView.setScrollViewCallbacks(this); textView.setText(readAssets()); } private String readAssets() { String loremString = ""; BufferedReader reader = null; try { reader = new BufferedReader( new InputStreamReader(getAssets().open("loremipsum.txt"), "UTF-8")); String mLine = reader.readLine(); while (mLine != null) { mLine = reader.readLine(); loremString += mLine; } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return loremString; } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { ActionBar ab = getSupportActionBar(); if (ab == null) { return; } if (scrollState == ScrollState.UP) { if (ab.isShowing()) { ab.hide(); } } else if (scrollState == ScrollState.DOWN) { if (!ab.isShowing()) { ab.show(); } } } }And a WebViewActivity, in this, customizing an own WebViewClient to make WebView more "friendly":
package devexchanges.info.autohideactionbar; import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ObservableWebView; import com.github.ksoichiro.android.observablescrollview.ScrollState; /** */ public class WebViewActivity extends AppCompatActivity implements ObservableScrollViewCallbacks { private ObservableWebView webView; private ProgressBar progressBar; @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web); webView = (ObservableWebView) findViewById(R.id.web); progressBar = (ProgressBar) findViewById(R.id.loading); webView.setScrollViewCallbacks(this); webView.getSettings().setJavaScriptEnabled(true); // enable javascript webView.setWebViewClient(new MyWebViewClient()); webView.loadUrl("http://www.devexchanges.info/"); } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { ActionBar ab = getSupportActionBar(); if (ab == null) { return; } if (scrollState == ScrollState.UP) { if (ab.isShowing()) { ab.hide(); } } else if (scrollState == ScrollState.DOWN) { if (!ab.isShowing()) { ab.show(); } } } private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { progressBar.setVisibility(View.GONE); WebViewActivity.this.progressBar.setProgress(100); super.onPageFinished(view, url); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { WebViewActivity.this.progressBar.setProgress(0); super.onPageStarted(view, url, favicon); } } }Over here, our project have almost complete. Final step is provide an activity to redirect to each screen, it will launch when app start, code for this main activity is so simple like this:
package devexchanges.info.autohideactionbar; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); View textListView = findViewById(R.id.txt_list); View textWebView = findViewById(R.id.txt_web); View textScrollView = findViewById(R.id.txt_scroll); // set event handling for TextViews // go to other Activity when each item was clicked textListView.setOnClickListener(onClickListener(ListViewActivity.class)); textScrollView.setOnClickListener(onClickListener(ScrollViewActivity.class)); textWebView.setOnClickListener(onClickListener(WebViewActivity.class)); } private View.OnClickListener onClickListener(final Class c) { return new View.OnClickListener() { @Override public void onClick(View view) { goToActivity(c); } }; } private void goToActivity(Class c) { Intent intent = new Intent(this, c); startActivity(intent); } }It's layout (only include 3 TextViews):
This main screen when app run:
Conclusion & References
- Libary project on @Github: https://github.com/ksoichiro/Android-ObservableScrollView
- If you can read Japanese, visit author blog to get more information! :)