当回收站视图中的第一项不可见但在第一项可见时隐藏时,如何在滚动上显示我的工厂?
How do I show my fab on scroll when the first item in the recycler view is not visible but hide when the first item is visible?
所以我正在尝试实现一个 FAB 按钮,这样当我滚动我的回收站视图并且第一个项目不可见(向上滚动等)时,fab 按钮应该是可见的,否则如果第一个项目应该隐藏位置正在显示。现在我已经实现了代码,但是它根本没有显示 fab 按钮,只是想知道我做错了什么?
我的xml代码如下:
<Linearlayout ....
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pullToRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/emailFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email"
app:layout_anchor="@id/myRecyclerView"
android:layout_gravity="bottom|end"
app:layout_behavior="com.example.fab.ScrollAwareFABBehavior"
app:layout_anchorGravity="bottom|end"
/>
</FrameLayout>
</LinearLayout>
我的 Kotlin 代码如下:
val positionView = (myRecyclerView.getLayoutManager() as LinearLayoutManager).findFirstVisibleItemPosition()
myRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (dy >0 && positionView > 0) {
emailFab.show();
} else {
emailFab.hide();
}
}
有什么想法吗?
谢谢!
此代码 100% 有效:
public class TestActivity extends AppCompatActivity {
private static final String TAG = "TestActivity";
private ArrayList<String> datas = new ArrayList<>();
private FloatingActionButton fabButton;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private DataAdapter dataAdapter;
private boolean isFabVisible = false;
private OnFabVisibilityCallback onFabVisibilityCallback;
public void setOnFabVisibilityCallback(OnFabVisibilityCallback onFabVisibilityCallback) {
this.onFabVisibilityCallback = onFabVisibilityCallback;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_contacts);
datas.add("one");
datas.add("two");
datas.add("three");
datas.add("four");
datas.add("five");
datas.add("six");
datas.add("seven");
datas.add("eight");
datas.add("nine");
datas.add("ten");
fabButton = (FloatingActionButton)findViewById(R.id.fabButton);
fabButton.setVisibility(View.GONE);
recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
dataAdapter = new DataAdapter(this, datas);
recyclerView.setAdapter(dataAdapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if(linearLayoutManager.findFirstVisibleItemPosition() == 0){
//hide
if(onFabVisibilityCallback != null){
onFabVisibilityCallback.onChange(false);
}
}else{
//show
if(onFabVisibilityCallback != null){
onFabVisibilityCallback.onChange(true);
}
}
}
});
setOnFabVisibilityCallback(new OnFabVisibilityCallback() {
@Override
public void onChange(boolean isVisible) {
if(isVisible){
if(!isFabVisible){
isFabVisible = true;
fabButton.setVisibility(View.VISIBLE);
}
}else{
if(isFabVisible){
isFabVisible = false;
fabButton.setVisibility(View.GONE);
}
}
}
});
}
private class DataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Activity activity;
private ArrayList<String> datas;
private LayoutInflater layoutInflater;
public DataAdapter(Activity activity, ArrayList<String> datas) {
this.activity = activity;
this.datas = datas;
this.layoutInflater = LayoutInflater.from(activity);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new SimpleViewHolder(layoutInflater.inflate(R.layout.unit_test, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
((SimpleViewHolder)holder).init(datas.get(position));
}
@Override
public int getItemCount() {
return datas.size();
}
private class SimpleViewHolder extends RecyclerView.ViewHolder{
private TextView text;
public SimpleViewHolder(View itemView) {
super(itemView);
initViews(itemView);
}
private void initViews(View v){
text = (TextView)v.findViewById(R.id.text);
}
public void init(String data){
text.setText(data);
}
}
}
public interface OnFabVisibilityCallback{
void onChange(boolean isVisible);
}
}
activity 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:src="@drawable/ic_add_black_24dp"
android:tint="@color/white" />
</RelativeLayout>
这是 recyclerview 子布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:gravity="center"
android:background="@color/yellow"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp">
<TextView
android:text="data"
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
我认为问题在于您应该将 findFirstVisibleItemPosition()
拉入 OnScrollListener
以找到滚动更改中的可见位置:
myRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val positionView = (myRecyclerView.getLayoutManager() as LinearLayoutManager).findFirstVisibleItemPosition()
if (positionView > 0) {
if(!emailFab.isShown) {
emailFab.show();
}
} else {
if(emailFab.isShown) {
emailFab.hide();
}
}
}
})
所以我正在尝试实现一个 FAB 按钮,这样当我滚动我的回收站视图并且第一个项目不可见(向上滚动等)时,fab 按钮应该是可见的,否则如果第一个项目应该隐藏位置正在显示。现在我已经实现了代码,但是它根本没有显示 fab 按钮,只是想知道我做错了什么?
我的xml代码如下:
<Linearlayout ....
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pullToRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/emailFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email"
app:layout_anchor="@id/myRecyclerView"
android:layout_gravity="bottom|end"
app:layout_behavior="com.example.fab.ScrollAwareFABBehavior"
app:layout_anchorGravity="bottom|end"
/>
</FrameLayout>
</LinearLayout>
我的 Kotlin 代码如下:
val positionView = (myRecyclerView.getLayoutManager() as LinearLayoutManager).findFirstVisibleItemPosition()
myRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (dy >0 && positionView > 0) {
emailFab.show();
} else {
emailFab.hide();
}
}
有什么想法吗?
谢谢!
此代码 100% 有效:
public class TestActivity extends AppCompatActivity {
private static final String TAG = "TestActivity";
private ArrayList<String> datas = new ArrayList<>();
private FloatingActionButton fabButton;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private DataAdapter dataAdapter;
private boolean isFabVisible = false;
private OnFabVisibilityCallback onFabVisibilityCallback;
public void setOnFabVisibilityCallback(OnFabVisibilityCallback onFabVisibilityCallback) {
this.onFabVisibilityCallback = onFabVisibilityCallback;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_contacts);
datas.add("one");
datas.add("two");
datas.add("three");
datas.add("four");
datas.add("five");
datas.add("six");
datas.add("seven");
datas.add("eight");
datas.add("nine");
datas.add("ten");
fabButton = (FloatingActionButton)findViewById(R.id.fabButton);
fabButton.setVisibility(View.GONE);
recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
dataAdapter = new DataAdapter(this, datas);
recyclerView.setAdapter(dataAdapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if(linearLayoutManager.findFirstVisibleItemPosition() == 0){
//hide
if(onFabVisibilityCallback != null){
onFabVisibilityCallback.onChange(false);
}
}else{
//show
if(onFabVisibilityCallback != null){
onFabVisibilityCallback.onChange(true);
}
}
}
});
setOnFabVisibilityCallback(new OnFabVisibilityCallback() {
@Override
public void onChange(boolean isVisible) {
if(isVisible){
if(!isFabVisible){
isFabVisible = true;
fabButton.setVisibility(View.VISIBLE);
}
}else{
if(isFabVisible){
isFabVisible = false;
fabButton.setVisibility(View.GONE);
}
}
}
});
}
private class DataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Activity activity;
private ArrayList<String> datas;
private LayoutInflater layoutInflater;
public DataAdapter(Activity activity, ArrayList<String> datas) {
this.activity = activity;
this.datas = datas;
this.layoutInflater = LayoutInflater.from(activity);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new SimpleViewHolder(layoutInflater.inflate(R.layout.unit_test, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
((SimpleViewHolder)holder).init(datas.get(position));
}
@Override
public int getItemCount() {
return datas.size();
}
private class SimpleViewHolder extends RecyclerView.ViewHolder{
private TextView text;
public SimpleViewHolder(View itemView) {
super(itemView);
initViews(itemView);
}
private void initViews(View v){
text = (TextView)v.findViewById(R.id.text);
}
public void init(String data){
text.setText(data);
}
}
}
public interface OnFabVisibilityCallback{
void onChange(boolean isVisible);
}
}
activity 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:src="@drawable/ic_add_black_24dp"
android:tint="@color/white" />
</RelativeLayout>
这是 recyclerview 子布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:gravity="center"
android:background="@color/yellow"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp">
<TextView
android:text="data"
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
我认为问题在于您应该将 findFirstVisibleItemPosition()
拉入 OnScrollListener
以找到滚动更改中的可见位置:
myRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val positionView = (myRecyclerView.getLayoutManager() as LinearLayoutManager).findFirstVisibleItemPosition()
if (positionView > 0) {
if(!emailFab.isShown) {
emailFab.show();
}
} else {
if(emailFab.isShown) {
emailFab.hide();
}
}
}
})