gpt4 book ai didi

java - 添加和删​​除水平列表项 onScroll

转载 作者:太空宇宙 更新时间:2023-11-03 13:01:35 26 4
gpt4 key购买 nike

我需要显示水平 ListView 项目的无限滚动(意味着需要重复项目)例如

a,b,c,d,e,f,a,b,c,d,e,f,a,b,....

粗体是屏幕上可见的项目

过程是在到达最后一个列表项后重复列表项,我尝试在滚动列表时添加列表项,所以我自定义了水平 ListView 类。但是在右侧添加列表项后向左滚动时,我得到了 ArrayIndexOutOfBoundsException。我试图在基本适配器中添加 Integer.MAX VALUE 选项以获得无限数量的项目,但它在定位项目时没有帮助(设置选择())。如果有人知道如何添加和删除水平列表项的方法,请分享。

最佳答案

不是扩展 BaseAdapter 而是扩展 ArrayAdapter。

解决方案 1::

注意::在 AgarwalActivity.java 中为水平 ListView 设置 boolean 变量 isHorizo​​ntalListView = true。

Horizo​​ntalListView.java

public class HorizontalListView extends AdapterView<ListAdapter> {

public boolean mAlwaysOverrideTouch = true;
protected ListAdapter mAdapter;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mDisplayOffset = 0;
protected Scroller mScroller;
private GestureDetector mGesture;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;


public HorizontalListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}

private synchronized void initView() {
mLeftViewIndex = -1;
mRightViewIndex = 0;
mDisplayOffset = 0;
mCurrentX = 0;
mNextX = 0;
mMaxX = Integer.MAX_VALUE;
mScroller = new Scroller(getContext());
mGesture = new GestureDetector(getContext(), mOnGesture);
}

@Override
public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {
mOnItemSelected = listener;
}

@Override
public void setOnItemClickListener(AdapterView.OnItemClickListener listener){
mOnItemClicked = listener;
}

@Override
public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener) {
mOnItemLongClicked = listener;
}

private DataSetObserver mDataObserver = new DataSetObserver() {

@Override
public void onChanged() {
synchronized(HorizontalListView.this){
mDataChanged = true;
}
invalidate();
requestLayout();
}

@Override
public void onInvalidated() {
reset();
invalidate();
requestLayout();
}

};

@Override
public ListAdapter getAdapter() {
return mAdapter;
}

@Override
public View getSelectedView() {
//TODO: implement
return null;
}

@Override
public void setAdapter(ListAdapter adapter) {
if(mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataObserver);
}
mAdapter = adapter;
mAdapter.registerDataSetObserver(mDataObserver);
reset();
}

private synchronized void reset(){
initView();
removeAllViewsInLayout();
requestLayout();
}

@Override
public void setSelection(int position) {
//TODO: implement
}

private void addAndMeasureChild(final View child, int viewPos) {
LayoutParams params = child.getLayoutParams();
if(params == null) {
params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
}

addViewInLayout(child, viewPos, params, true);
child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
}

@Override
protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);

if(mAdapter == null){
return;
}

if(mDataChanged){
int oldCurrentX = mCurrentX;
initView();
removeAllViewsInLayout();
mNextX = oldCurrentX;
mDataChanged = false;
}

if(mScroller.computeScrollOffset()){
int scrollx = mScroller.getCurrX();
mNextX = scrollx;
}

if(mNextX <= 0){
mNextX = 0;
mScroller.forceFinished(true);
}
if(mNextX >= mMaxX) {
mNextX = mMaxX;
mScroller.forceFinished(true);
}

int dx = mCurrentX - mNextX;

removeNonVisibleItems(dx);
fillList(dx);
positionItems(dx);

mCurrentX = mNextX;

if(!mScroller.isFinished()){
post(new Runnable() {

public void run() {
// TODO Auto-generated method stub
requestLayout();
}
});

}
}

private void fillList(final int dx) {
int edge = 0;
View child = getChildAt(getChildCount()-1);
if(child != null) {
edge = child.getRight();
}
fillListRight(edge, dx);

edge = 0;
child = getChildAt(0);
if(child != null) {
edge = child.getLeft();
}
fillListLeft(edge, dx);


}

private void fillListRight(int rightEdge, final int dx) {
while(rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {

View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, -1);
rightEdge += child.getMeasuredWidth();

if(mRightViewIndex == mAdapter.getCount()-1) {
mMaxX = mCurrentX + rightEdge - getWidth();
}

if (mMaxX < 0) {
mMaxX = 0;
}
mRightViewIndex++;
}

}

private void fillListLeft(int leftEdge, final int dx) {
while(leftEdge + dx > 0 && mLeftViewIndex >= 0) {
View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, 0);
leftEdge -= child.getMeasuredWidth();
mLeftViewIndex--;
mDisplayOffset -= child.getMeasuredWidth();
}
}

private void removeNonVisibleItems(final int dx) {
View child = getChildAt(0);
while(child != null && child.getRight() + dx <= 0) {
mDisplayOffset += child.getMeasuredWidth();
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mLeftViewIndex++;
child = getChildAt(0);

}

child = getChildAt(getChildCount()-1);
while(child != null && child.getLeft() + dx >= getWidth()) {
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mRightViewIndex--;
child = getChildAt(getChildCount()-1);
}
}

private void positionItems(final int dx) {
if(getChildCount() > 0){
mDisplayOffset += dx;
int left = mDisplayOffset;
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int childWidth = child.getMeasuredWidth();
child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
left += childWidth;
}
}
}

public synchronized void scrollTo(int x) {
mScroller.startScroll(mNextX, 0, x - mNextX, 0);
requestLayout();
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean handled = super.dispatchTouchEvent(ev);
handled |= mGesture.onTouchEvent(ev);
return handled;
}

protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
synchronized(HorizontalListView.this){
mScroller.fling(mNextX, 0, (int)-velocityX, 0, 0, mMaxX, 0, 0);
}
requestLayout();

return true;
}

protected boolean onDown(MotionEvent e) {
mScroller.forceFinished(true);
return true;
}

private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {

@Override
public boolean onDown(MotionEvent e) {
return HorizontalListView.this.onDown(e);
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {

synchronized(HorizontalListView.this){
mNextX += (int)distanceX;
}
requestLayout();

return true;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
if (isEventWithinView(e, child)) {
if(mOnItemClicked != null){
mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
break;
}

}
return true;
}

@Override
public void onLongPress(MotionEvent e) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (isEventWithinView(e, child)) {
if (mOnItemLongClicked != null) {
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}

}
}

private boolean isEventWithinView(MotionEvent e, View child) {
Rect viewRect = new Rect();
int[] childPosition = new int[2];
child.getLocationOnScreen(childPosition);
int left = childPosition[0];
int right = left + child.getWidth();
int top = childPosition[1];
int bottom = top + child.getHeight();
viewRect.set(left, top, right, bottom);
return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
}
};



}

AgarwalActivity.java

public class AgarwalActivity extends Activity{

private LayoutInflater _inflater;
private ListView listView;
private HorizontalListView hListView;
private RankingsAdapter rankingsAdapter;
private boolean isHorizontalListView = false;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(isHorizontalListView){
setContentView(R.layout.listviewdemo);
hListView = (HorizontalListView) findViewById(R.id.listview);
}else{
setContentView(R.layout.listview);
listView=(ListView)findViewById(R.id.listView);
}

ArrayList<String> rankingArrayList = new ArrayList<String>();
for(int i=0;i<25;i++)
rankingArrayList.add("agarwal"+i);

_inflater= LayoutInflater.from(AgarwalActivity.this);

rankingsAdapter = new RankingsAdapter(AgarwalActivity.this,R.id.text,rankingArrayList);
if(isHorizontalListView)
hListView.setAdapter(rankingsAdapter);
else
listView.setAdapter(rankingsAdapter);

}


private class RankingsAdapter extends ArrayAdapter<String>{
private ArrayList<String> _row_list;

public static final int HALF_MAX_VALUE = Integer.MAX_VALUE/2;
public final int MIDDLE;
public RankingsAdapter(Context context,int textViewResourceId,ArrayList<String> arrL) {
// TODO Auto-generated constructor stub
super(context,textViewResourceId, arrL);
_row_list = arrL;
MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % _row_list.size();
}
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}
public String getItem(int position) {
// TODO Auto-generated method stub
return _row_list.get(position % _row_list.size());
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position % _row_list.size();
}

public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;

if(convertView == null){
holder = new ViewHolder();
convertView = (LinearLayout)_inflater.inflate(R.layout.text_layout, null);
//getting the IDs
holder.driver = (TextView)convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {

holder=(ViewHolder)convertView.getTag();
}
//Settng bean values to row components
holder.driver.setText(_row_list.get(position % _row_list.size()));

return convertView;
}//getView()

class ViewHolder{
//holding the components
TextView driver;
}//ViewHolder--Class inside CountriesAdapter

}//RankingsAdapter-inner class

}//AgarwalActivity-class

listview.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >


<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

</ListView>

</RelativeLayout>

listviewdemo.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
>

<com.vl.agarwal.HorizontalListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ddd"
/>

</LinearLayout>

text_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >


<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="6dip"
android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

-------------------------------------------- --------------------------------------

解决方案 2:: 使用图库作为水平 ListView

行.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/itemtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:textColor="@android:color/white"
android:textStyle="bold"
android:textSize="30sp"/>

</LinearLayout>

ma​​in.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Gallery
android:id="@+id/horizontallistview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

</LinearLayout>

AgarwalActivity.java

public class AgarwalActivity extends Activity {

Gallery myHorizontalListView;

private RankingsAdapter rankingsAdapter;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<String> rankingArrayList = new ArrayList<String>();
for(int i=0;i<25;i++)
rankingArrayList.add("agarwal"+i);

DisplayMetrics metrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(metrics);

myHorizontalListView = (Gallery)findViewById(R.id.horizontallistview);
MarginLayoutParams mlp = (MarginLayoutParams) myHorizontalListView.getLayoutParams();
mlp.setMargins(-(metrics.widthPixels/2),
mlp.topMargin,
mlp.rightMargin,
mlp.bottomMargin
);


rankingsAdapter = new RankingsAdapter(AgarwalActivity.this,R.id.itemtext,rankingArrayList);
myHorizontalListView.setAdapter(rankingsAdapter);

myHorizontalListView.setSelection(10,true);

myHorizontalListView.setOnItemClickListener(new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(
AgarwalActivity.this,
parent.getItemAtPosition(position).toString() + " Clicked",
Toast.LENGTH_LONG)
.show();

}});

}




private class RankingsAdapter extends ArrayAdapter<String>{
private ArrayList<String> _row_list;

public static final int HALF_MAX_VALUE = Integer.MAX_VALUE/2;
public final int MIDDLE;
public RankingsAdapter(Context context,int textViewResourceId,ArrayList<String> arrL) {
// TODO Auto-generated constructor stub
super(context,textViewResourceId, arrL);
_row_list = arrL;
MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % _row_list.size();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}
@Override
public String getItem(int position) {
// TODO Auto-generated method stub
return _row_list.get(position % _row_list.size());
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position % _row_list.size();
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View rowView = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.row, null);
TextView listTextView = (TextView)rowView.findViewById(R.id.itemtext);
listTextView.setText(_row_list.get(position % _row_list.size()));

return rowView;
}//getView()
}//RankingsAdapter-inner class
}//AgarwalActivity-class

关于java - 添加和删​​除水平列表项 onScroll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10527924/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com