新しいToolbar
、Tablayout
、およびViewpager
をAndroidアプリに追加しました。3つのタブにフラグメントを提供し、正常に機能しました。しかし、問題は、ツールバーを上にスクロールしても非表示にならないということです。フラグメントをスクロールすると非表示になるようにしたいということです。
MainActivity.Java
public class MainActivity extends AppCompatActivity {
TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupToolbar();
setupTablayout();
}
private void setupToolbar() {
// TODO Auto-generated method stub
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarsdfs);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);}
}
private void setupTablayout() {
// TODO Auto-generated method stub
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}
main.xml
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/coordinatorLayout"
Android:layout_height="match_parent"
Android:layout_width="match_parent">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbarsdfs"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:minHeight="?attr/actionBarSize"
Android:background="?attr/colorPrimaryDark"
Android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:layout_scrollFlags="scroll|enterAlways"/>
<Android.support.design.widget.TabLayout
Android:id="@+id/tabLayout"
Android:scrollbars="horizontal"
Android:layout_below="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="?attr/colorPrimary" />
<Android.support.v4.view.ViewPager
Android:id="@+id/pager"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:layout_below="@+id/tablayout"/>
</Android.support.design.widget.AppBarLayout>
</Android.support.design.widget.CoordinatorLayout>
PagerAdapter.Java
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment_Feeds tab1 = new Fragment_Feeds();
return tab1;
case 1:
Fragment_Facts tab2 = new Fragment_Facts();
return tab2;
default:
return null;
}
}
@Override
public int getCount() {
return mNumOfTabs;
}
}
Fragment_Feeds.Java
public class Fragment_Feeds extends Fragment {
SwipeRefreshLayout swipeView;
WebView myWebView;
ProgressBar progressBar;
final static String myBlogAddr = "http://myblog.com";
String myUrl;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragmentfeeds, container, false);
swipeView = (SwipeRefreshLayout) view.findViewById(R.id.swipe);
myWebView = (WebView) view.findViewById(R.id.webview);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
myWebView.setWebViewClient(new MyWebViewClient());
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.setOverScrollMode(View.OVER_SCROLL_NEVER);
myWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
myWebView.setHorizontalScrollBarEnabled(false);
myWebView.loadUrl("http://myblog.com");
swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
{
@Override
public void onRefresh()
{
myWebView.loadUrl("http://myblog.com");
}});
return view;
}
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
swipeView.setRefreshing(false);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
myUrl = url;
view.loadUrl(url);
return true;
}
@Override
public void onReceivedError(WebView view, int errorCod,String description, String failingUrl) {
myWebView.loadUrl("file:///Android_asset/error_page.html");
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
fragmentfeeds.xml
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical"
Android:background="#FFFFFF" >
<ProgressBar
Android:id="@+id/progressBar"
style="?android:attr/progressBarStyleSmall"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
<Android.support.v4.widget.SwipeRefreshLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/swipe"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#FFFFFF">s
<WebView
Android:id="@+id/webview"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:numColumns="1"
Android:scrollbars="none"
Android:focusableInTouchMode="false"
Android:focusable="false"
Android:background="#FFFFFF" />
</Android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
私が欲しいもの
私が欲しいのは、ウェブビューを上にスクロールするとツールバーも上にスクロールして非表示になり、下にスクロールするとツールバーができるだけ早く戻ることです。
これを試して。
main.xml
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/coordinatorLayout"
Android:layout_height="match_parent"
Android:layout_width="match_parent"
Android:fitsSystemWindows="true">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:fitsSystemWindows="true">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbarsdfs"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"/>
<Android.support.design.widget.TabLayout
Android:id="@+id/tabLayout"
Android:scrollbars="horizontal"
Android:layout_below="@+id/toolbarsdfs"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="?attr/colorPrimary"
app:tabTextColor="@Android:color/white"
app:tabSelectedTextColor="@Android:color/white"
app:tabIndicatorColor="@Android:color/white"
app:tabIndicatorHeight="3dp" />
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
Android:id="@+id/pager"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
Android:layout_below="@+id/tablayout"/>
</Android.support.design.widget.CoordinatorLayout>
fragmentfeeds.xml
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.NestedScrollView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:isScrollContainer="false"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="fill_vertical"
Android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<ProgressBar
Android:id="@+id/progressBar"
style="?android:attr/progressBarStyleSmall"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
<Android.support.v4.widget.SwipeRefreshLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/swipe"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#FFFFFF">
<WebView
Android:id="@+id/webviewtool"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:numColumns="1"
Android:focusableInTouchMode="false"
Android:focusable="false"
Android:background="#FFFFFF" />
</Android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
まず、WebビューをNestedScrollViewに移動し、「Android:isScrollContainer」プロパティを「false」値に設定する必要があります。 https://developer.Android.com/reference/Android/support/v4/widget/NestedScrollView.html
次に、ViewPagerをAppBarLayoutの外側に移動する必要があります。したがって、main.xmlは次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:background="#FFF"
Android:clickable="true"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- your app bar stuff here -->
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="240dp"
app:layout_scrollFlags="scroll|enterAlways">
<ImageView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scaleType="fitXY"
Android:id="@+id/image_header"/>
<include layout="@layout/header"/>
</FrameLayout>
<Android.support.design.widget.TabLayout
Android:id="@+id/tabs"
Android:background="#FFF"
app:tabTextColor="#a3a3a3"
app:tabSelectedTextColor="#a3a3a3"
app:tabIndicatorColor="#0042ab"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
/>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
Android:id="@+id/viewpager"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
Android:background="#eaeaea"/>
AppBarLayout childernはフラグapp:layout_scrollFlagsがある場合のみ非表示になります
サポートデザインライブラリの実装の詳細については、こちらをご覧ください。
https://Android-developers.googleblog.com/2015/05/Android-design-support-library.html
ViewPagerをAppBarLayoutの外側に移動し、ViewPagerに動作を追加する必要がありますapp:layout_behavior="@string/appbar_scrolling_view_behavior"
完全な例を書いた! https://github.com/erikcaffrey/AndroidDesignSupportLibrary
お役に立てばと思います!
私の英語についてすみません。
アプリ用にどのように作成したかを示します(最小SDK:14、ターゲットSDK:22)。私はフラグメントを使用しません。アクティビティには単一のWebビューしかありませんが、ハンドラーは同じです。問題は、WebView内でスクロールすると、Androidはスクロールイベントのように処理せず、WebViewは自分のイベントを処理します。
まず、resフォルダーでstyles.xmlを定義します。私は、透明でオーバーレイされたActionBarを使用します。
res/styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="@Android:style/Theme.Holo">
<!-- Customize your theme here. -->
<item name="Android:windowActionBarOverlay">true</item>
<item name="Android:actionBarStyle">@style/MyActionBar</item>
</style>
<!-- ACTION BAR STYLES -->
<style name="MyActionBar" parent="@Android:style/Widget.Holo.ActionBar">
<item name="Android:background">@color/actionbar_background</item>
</style>
</resources>
次に、マニフェストで、アプリケーションセクションでアプリとActionBarのスタイルを定義します。
<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/AppTheme" >
<activity
Android:name=".MainActivity"
Android:label="@string/app_name" >
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
最後にMainActivityで、WebViewのジェスチャーを制御する必要があります。 View.OnTouchListenerとHandler.Callbackを実装する必要があります。 Webビューをタッチするとき、開始イベントと終了イベントを比較する必要があります。
MainActivity.Java
public class MainActivity extends Activity implements View.OnTouchListener, Handler.Callback {
private float x1,x2,y1,y2; //x1, y1 is the start of the event, x2, y2 is the end.
static final int MIN_DISTANCE = 150; //min distance for a scroll up event
private static final int CLICK_ON_WEBVIEW = 1;
private static final int CLICK_ON_URL = 2;
private static final int UP_ON_WEBVIEW = 3;
private final Handler handler = new Handler(this);
public WebView webView;
private WebViewClient client;
private WebAppInterface webAppInt = new WebAppInterface(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.myWebView);
webView.setOnTouchListener(this);
client = new WebViewClient();
webView.setWebViewClient(client);
webView.loadDataWithBaseURL("file:///Android_asset/", "myweb.html", "text/html", "UTF-8", "");
}
//HERE START THE IMPORTANT PART
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_DOWN){
x1 = event.getX();
y1 = event.getY();
handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 200);
} else if (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_UP){
x2 = event.getX();
y2 = event.getY();
handler.sendEmptyMessageDelayed(UP_ON_WEBVIEW, 200);
}
return false;
}
@Override
public boolean handleMessage(Message msg) {
if (msg.what == CLICK_ON_URL){ //if you clic a link in the webview, thats not a scroll
handler.removeMessages(CLICK_ON_WEBVIEW);
handler.removeMessages(UP_ON_WEBVIEW);
return true;
}
if (msg.what == CLICK_ON_WEBVIEW){
Toast.makeText(this, "WebView clicked", Toast.LENGTH_SHORT).show();
return true;
}
if (msg.what == UP_ON_WEBVIEW){
float deltaX = x2 - x1; //horizontal move distance
float deltaY = y2 - y1; //vertical move distance
if ((Math.abs(deltaX) > MIN_DISTANCE) && (Math.abs(deltaX) > Math.abs(deltaY)))
{
// Left to Right swipe action
if (x2 > x1)
{
Toast.makeText(this, "Left to Right swipe [Next]", Toast.LENGTH_SHORT).show ();
}
// Right to left swipe action
else
{
Toast.makeText(this, "Right to Left swipe [Previous]", Toast.LENGTH_SHORT).show ();
}
}
else if ((Math.abs(deltaY) > MIN_DISTANCE) && (Math.abs(deltaY) > Math.abs(deltaX)))
{
// Top to Bottom swipe action -- i SWOW MY ACTIONBAR ON SCROLLDOWN
if (y2 > y1)
{
getActionBar().show();
Toast.makeText(this, "Top to Bottom swipe [Show Bar]", Toast.LENGTH_SHORT).show ();
}
// Bottom to top swipe action -- I HIDE MY ACTIONBAR ON SCROLLUP
else
{
getActionBar().hide();
Toast.makeText(this, "Bottom to Top swipe [Hide Bar]", Toast.LENGTH_SHORT).show ();
}
}
return true;
}
return false;
}
}
それがお役に立てば幸いです。
この行をツールバーまたはFABボタンに追加するだけです。
app:layout_scrollFlags="scroll|enterAlways"
app:layout_scrollFlags="scroll|enterAlways"
行により、ユーザーがリストを下にスクロールするとToolbar
が画面をスクロールし、上にスクロールし始めるとすぐにToolbar
が再び表示されます。クリーンでシンプル、それがCoordinatorLayout
の力です!
ツールバーのプロパティを変更します。
app:layout_scrollFlags = "scroll | exitUntilCollapsed"
特定のフラグメントのメニューを非表示にするには:
setHasOptionsMenu(true); //Inside of onCreate in FRAGMENT:
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_search).setVisible(false);
}