在我的Android应用程序中,我有一个recyclerview和LinearLayout。 LinearLayout位于顶部,recyclelerview位于线性布局。我的要求是当recyclerview开始滚动最后一项时,线性布局应该开始隐藏在滚动量的比例中。
我做了一点而且有效。但它与滚动量不成比例。这是我的代码
ScrollListener
public class MyScrollListener extends OnScrollListener {
private LinearLayoutManager mLayoutManager;
public MyScrollListener(LinearLayoutManager manager) {
this.mLayoutManager = manager;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (visibleItemCount + firstVisibleItem >= totalItemCount) {
scrollTheShit(dy * -1, ((View) recyclerView.getChildAt(visibleItemCount - 1)).getWidth());
}
}
public void scrollTheShit(int dy, int widthOfLastChild) {}
}
MainActivity
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = (LinearLayout) findViewById(R.id.container);
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
final LinearLayoutManager mgr = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mgr);
recyclerView.setAdapter(new RecyclerAdapter());
recyclerView.addOnScrollListener(new MyScrollListener(mgr) {
@Override
public void scrollTheShit(int dy, int widthOfLastChild) {
linearLayout.setY(linearLayout.getY() + dy );
}
});
}
private class RecyclerAdapter extends Adapter<RecyclerAdapter.ViewHolder> {
@Override
public int getItemCount() {
return 10;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder,
int position) {
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
View v = LayoutInflater.from(MainActivity.this)
.inflate(R.layout.child, parent, false);
ViewHolder holder = new ViewHolder(v);
return holder;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View arg0) {
super(arg0);
}
}
}
}
我该如何纠正?有人请帮助我
答案 0 :(得分:0)
这可能会对你有所帮助
QuickReturnRecyclerView.java
import android.content.Context;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
public class QuickReturnRecyclerView extends RecyclerView {
private static final String TAG = QuickReturnRecyclerView.class.getName();
private View mReturningView;
private static final int STATE_ONSCREEN = 0;
private static final int STATE_OFFSCREEN = 1;
private static final int STATE_RETURNING = 2;
private int mState = STATE_ONSCREEN;
private int mMinRawY = 0;
private int mReturningViewHeight;
private int mGravity = Gravity.BOTTOM;
public QuickReturnRecyclerView(Context context) {
super(context);
init();
}
public QuickReturnRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public QuickReturnRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
}
/**
* The view that should be showed/hidden when scrolling the content.
* Make sure to set the gravity on the this view to either Gravity.Bottom or
* Gravity.TOP and to put it preferable in a FrameLayout.
* @param view Any kind of view
*/
public void setReturningView(View view) {
mReturningView = view;
try {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mReturningView.getLayoutParams();
mGravity = params.gravity;
} catch (ClassCastException e) {
throw new RuntimeException("The return view need to be put in a FrameLayout");
}
measureView(mReturningView);
mReturningViewHeight = mReturningView.getMeasuredHeight();
addOnScrollListener(new RecyclerScrollListener());
}
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
private class RecyclerScrollListener extends OnScrollListener {
private int mScrolledY;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if(mGravity == Gravity.BOTTOM)
mScrolledY += dy;
else if(mGravity == Gravity.TOP)
mScrolledY -= dy;
if(mReturningView == null)
return;
int translationY = 0;
int rawY = mScrolledY;
switch (mState) {
case STATE_OFFSCREEN:
if(mGravity == Gravity.BOTTOM) {
if (rawY >= mMinRawY) {
mMinRawY = rawY;
} else {
mState = STATE_RETURNING;
}
} else if(mGravity == Gravity.TOP) {
if (rawY <= mMinRawY) {
mMinRawY = rawY;
} else {
mState = STATE_RETURNING;
}
}
translationY = rawY;
break;
case STATE_ONSCREEN:
if(mGravity == Gravity.BOTTOM) {
if (rawY > mReturningViewHeight) {
mState = STATE_OFFSCREEN;
mMinRawY = rawY;
}
} else if(mGravity == Gravity.TOP) {
if (rawY < -mReturningViewHeight) {
mState = STATE_OFFSCREEN;
mMinRawY = rawY;
}
}
translationY = rawY;
break;
case STATE_RETURNING:
if(mGravity == Gravity.BOTTOM) {
translationY = (rawY - mMinRawY) + mReturningViewHeight;
if (translationY < 0) {
translationY = 0;
mMinRawY = rawY + mReturningViewHeight;
}
if (rawY == 0) {
mState = STATE_ONSCREEN;
translationY = 0;
}
if (translationY > mReturningViewHeight) {
mState = STATE_OFFSCREEN;
mMinRawY = rawY;
}
} else if(mGravity == Gravity.TOP) {
translationY = (rawY + Math.abs(mMinRawY)) - mReturningViewHeight;
if (translationY > 0) {
translationY = 0;
mMinRawY = rawY - mReturningViewHeight;
}
if (rawY == 0) {
mState = STATE_ONSCREEN;
translationY = 0;
}
if (translationY < -mReturningViewHeight) {
mState = STATE_OFFSCREEN;
mMinRawY = rawY;
}
}
break;
}
/** this can be used if the build is below honeycomb **/
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB) {
TranslateAnimation anim = new TranslateAnimation(0, 0, translationY, translationY);
anim.setFillAfter(true);
anim.setDuration(0);
mReturningView.startAnimation(anim);
} else {
mReturningView.setTranslationY(translationY);
}
}
}
}
activity_main.xml中
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<yourpackagename.QuickReturnRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<LinearLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="@android:color/darker_gray"
android:orientation="horizontal"
android:padding="15dp">
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="left|top"
android:layout_weight="1"
android:text="New Button" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_weight="1"
android:text="New Button" />
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right|top"
android:layout_weight="1"
android:text="New Button" />
</LinearLayout>
</FrameLayout>
MainActivity.java
中的只需添加以下行
mRecyclerView = (QuickReturnRecyclerView) findViewById(R.id.recycler_view);
linear = (LinearLayout) findViewById(R.id.linear);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setReturningView(linear);