Created
April 3, 2020 11:45
-
-
Save IRMobydick/0e3fe4fc4bd90963cbc1d04e5f9b010d to your computer and use it in GitHub Desktop.
Custom Android AppBarLayout$ScrollingViewBehavior: Prevent Toolbar from scrolling when RecyclerView doesn't have enough items to scroll.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<!-- | |
~ Copyright 2016 Alireza Eskandarpour Shoferi | |
~ | |
~ Licensed under the Apache License, Version 2.0 (the "License"); | |
~ you may not use this file except in compliance with the License. | |
~ You may obtain a copy of the License at | |
~ | |
~ http://www.apache.org/licenses/LICENSE-2.0 | |
~ | |
~ Unless required by applicable law or agreed to in writing, software | |
~ distributed under the License is distributed on an "AS IS" BASIS, | |
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
~ See the License for the specific language governing permissions and | |
~ limitations under the License. | |
--> | |
<io.github.meness.testapplication.NotTouchableCoordinatorLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:fitsSystemWindows="false"> | |
<android.support.design.widget.AppBarLayout | |
android:id="@+id/appBarLayout" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:fitsSystemWindows="true" | |
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"> | |
<android.support.v7.widget.Toolbar | |
android:id="@+id/toolbar" | |
android:layout_width="match_parent" | |
android:layout_height="?attr/actionBarSize" | |
android:fitsSystemWindows="true" | |
app:layout_scrollFlags="scroll|enterAlways" | |
app:title="@string/app_name" | |
app:titleTextColor="@android:color/white"> | |
</android.support.v7.widget.Toolbar> | |
</android.support.design.widget.AppBarLayout> | |
<android.support.v7.widget.RecyclerView | |
android:id="@+id/rv" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:overScrollMode="never"> | |
</android.support.v7.widget.RecyclerView> | |
</io.github.meness.testapplication.NotTouchableCoordinatorLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<!-- | |
~ Copyright 2016 Alireza Eskandarpour Shoferi | |
~ | |
~ Licensed under the Apache License, Version 2.0 (the "License"); | |
~ you may not use this file except in compliance with the License. | |
~ You may obtain a copy of the License at | |
~ | |
~ http://www.apache.org/licenses/LICENSE-2.0 | |
~ | |
~ Unless required by applicable law or agreed to in writing, software | |
~ distributed under the License is distributed on an "AS IS" BASIS, | |
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
~ See the License for the specific language governing permissions and | |
~ limitations under the License. | |
--> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/name" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"/> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2016 Alireza Eskandarpour Shoferi | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import android.os.Bundle; | |
import android.support.design.widget.CoordinatorLayout; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import com.mikepenz.fastadapter.adapters.FastItemAdapter; | |
public class MainActivity extends AppCompatActivity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
// init | |
LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); | |
FastItemAdapter<SampleItem> adapter = new FastItemAdapter<>(); | |
RecyclerView rv = (RecyclerView) findViewById(R.id.rv); | |
// set behavior to RecyclerView | |
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) rv.getLayoutParams(); | |
params.setBehavior(new ShouldScrolledBehavior(layoutManager, adapter)); | |
rv.setLayoutParams(params); | |
rv.setLayoutManager(layoutManager); | |
rv.setHasFixedSize(true); | |
rv.setAdapter(adapter); | |
for (int i = 1; i < 100; i++) { | |
adapter.add(new SampleItem().setNumber(i)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2016 Alireza Eskandarpour Shoferi | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import android.content.Context; | |
import android.support.design.widget.CoordinatorLayout; | |
import android.util.AttributeSet; | |
import android.view.MotionEvent; | |
/** | |
* touching on CoordinatorLayout has disabled to only be scrolled while RecyclerView is scrolling | |
*/ | |
public class NotTouchableCoordinatorLayout extends CoordinatorLayout { | |
public NotTouchableCoordinatorLayout(Context context) { | |
super(context); | |
} | |
public NotTouchableCoordinatorLayout(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
public NotTouchableCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
} | |
@Override | |
public boolean onInterceptTouchEvent(MotionEvent ev) { | |
return false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2016 Alireza Eskandarpour Shoferi | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import android.support.v7.widget.RecyclerView; | |
import android.view.View; | |
import android.widget.TextView; | |
import com.mikepenz.fastadapter.items.AbstractItem; | |
import java.util.List; | |
public class SampleItem extends AbstractItem<SampleItem, SampleItem.ViewHolder> { | |
public int number; | |
public SampleItem setNumber(int number) { | |
this.number = number; | |
return this; | |
} | |
@Override | |
public int getType() { | |
return 0; | |
} | |
@Override | |
public int getLayoutRes() { | |
return R.layout.layout_sample_item; | |
} | |
@Override | |
public void bindView(ViewHolder holder, List payloads) { | |
super.bindView(holder, payloads); | |
holder.name.setText("Hello World " + number); | |
} | |
protected static class ViewHolder extends RecyclerView.ViewHolder { | |
protected TextView name; | |
public ViewHolder(View view) { | |
super(view); | |
this.name = (TextView) view.findViewById(R.id.name); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2016 Alireza Eskandarpour Shoferi | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import android.support.design.widget.AppBarLayout; | |
import android.support.design.widget.CoordinatorLayout; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import com.mikepenz.fastadapter.adapters.FastItemAdapter; | |
/** | |
* scroll when adapter's items are not completely visible. in other words, | |
* toolbar is always visible till adapter's items are enough to be scrolled. | |
*/ | |
public class ShouldScrolledBehavior extends AppBarLayout.ScrollingViewBehavior { | |
private LinearLayoutManager mLayoutManager; | |
private FastItemAdapter<SampleItem> mAdapter; | |
public ShouldScrolledBehavior(LinearLayoutManager layoutManager, FastItemAdapter<SampleItem> adapter) { | |
super(); | |
this.mLayoutManager = layoutManager; | |
this.mAdapter = adapter; | |
} | |
@Override | |
public boolean onInterceptTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) { | |
return !shouldScrolled(); | |
} | |
public boolean shouldScrolled() { | |
// adapter has more items that not shown yet | |
if (mLayoutManager.findLastCompletelyVisibleItemPosition() != mAdapter.getAdapterItemCount() - 1) { | |
return true; | |
} | |
// last completely visible item is the last item in adapter but it may be occurred in 2 ways: | |
// 1) all items are shown | |
// 2) scrolled to the last item (implemented following) | |
else if (mLayoutManager.findLastCompletelyVisibleItemPosition() == mAdapter.getAdapterItemCount() - 1 && mLayoutManager.findFirstCompletelyVisibleItemPosition() != 0) { | |
return true; | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment