我一直在使用mergeAdapter将多个列表视图合并在一起,没有任何问题。而现在,我想用它来合并顶部的列表视图,中间的横向视图滚动视图和底部的另一个列表视图,但到目前为止...我无法弄清楚如何做到这一点。如果有人能帮我一把,那就太好了......
以下是我现有的代码。
MyActivity
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_a);
lv = (ListView) findViewById(R.id.list_all);
adapter=new MergeAdapter();
infoArray = new ArrayList<Infos>();
photoArray = new ArrayList<Photos>();
commentArray = new ArrayList<Comments>();
infoAdapter = new InfoAdapter(MyActivity.this, R.layout.info_list_layout, infoArray);
/// photoAdapter = new PhotoAdapter(MyActivity.this, R.layout.photo_hscroll_layout, photoArray); /// STUCK
commentAdapter = new CommentAdapter(MyActivity.this, R.layout.comment_list_layout, commentArray);
lv.setTextFilterEnabled(true);
adapter.addAdapter(infoAdapter);
/// adapter.addAdapter(photoAdapter); //// STUCK
adapter.addAdapter(commentAdapter);
lv.setAdapter(adapter);
try {
new stuffSync().execute("http://www.StuckForDays.com/json");
} catch(Exception e) {}
}
private class stuffSync extends AsyncTask<String, Integer, stuffDetail> {
protected stuffDetail doInBackground(String... urls) {
stuffDetail list = null;
int count = urls.length;
for (int i = 0; i < count; i++) {
try {
//rest client
RestClient client = new RestClient(urls[i]);
try {
client.Execute(RequestMethod.GET);
} catch (Exception e) {
e.printStackTrace();
}
String json = client.getResponse();
list = new Gson().fromJson(json, stuffDetail.class);
//
} catch(Exception e) {}
}
return list;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(stuffDetail list) {
List<Infos> info = list.getInfo();
for (Infos info2 : info) {
infoArray.add(info2);
}
List<Photos> photos = list.getPhotos();
for (Photos photo : photos) {
photoArray.add(photo);
System.out.println(photo);
}
List<Comments> comments = list.getComments();
for (Comments comment : comments) {
commentArray.add(comment);
}
infoAdapter.notifyDataSetChanged();
// photoAdapter.notifyDataSetChanged(); //// STUCK
commentAdapter.notifyDataSetChanged();
}
}
infoAdapter和commentAdapter(几乎相同)
public class InfoAdapter extends ArrayAdapter<Infos> {
int resource;
String response;
Context context;
private LayoutInflater dInflater;
public InfoAdapter(Context context, int resource, List<Infos> objects) {
super(context, resource, objects);
this.resource = resource;
dInflater = LayoutInflater.from(context);
}
static class ViewHolder {
TextView realname;
TextView nickname;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
Infos lm = (Infos) getItem(position);
//Inflate the view
if(convertView==null)
{
convertView = dInflater.inflate(R.layout.info_list_layout, null);
holder = new ViewHolder();
holder.realname = (TextView) convertView.findViewById(R.id.realname);
holder.nickname = (TextView) convertView.findViewById(R.id.nickname);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.realname.setText(lm.getRealName());
holder.nickname.setText(lm.getNickname());
return convertView;
}
}
我的照片json
{
"photos" : [
{
"thumbnail" : "http://www.myserver.com/01.jpg"
},
{
"thumbnail" : "http://www.myserver.com/02.jpg"
},
{
"thumbnail" : "http://www.myserver.com/03.jpg"
}
]}
现在我被困在如何让photoArray创建中间部分水平滚动视图...我可以得到json并将它们添加到photoArray,只是不知道如何提取,创建视图和展示它。
提前感谢所有
答案 0 :(得分:0)
我认为问题用水平滚动视图解决..这是一个自定义控件..
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;
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;
private boolean mMeasureHeightForVisibleOnly = true;
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();
}
/**
* @param visibleOnly - If set to true, then height is calculated
* only using visible views. If set to false then height is
* calculated using _all_ views in adapter. Default is true.
* Be very careful when passing false, as this may result in
* significant performance hit for larger number of views.
*/
public void setHeightMeasureMode(boolean visibleOnly) {
if(mMeasureHeightForVisibleOnly != visibleOnly) {
mMeasureHeightForVisibleOnly = visibleOnly;
requestLayout();
}
}
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 void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
int height = 0;
if(mMeasureHeightForVisibleOnly) {
int childCount = getChildCount();
for(int i = 0; i < childCount; i++) {
View v = getChildAt(i);
v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if(v.getMeasuredHeight() > height) {
height = v.getMeasuredHeight();
}
}
} else {
/* Traverses _all_ views! Bypasses view recycler! */
HashMap<Integer, View> mRecycler = new HashMap<Integer, View>();
int childCount = getAdapter().getCount();
for(int i = 0; i < childCount; i++) {
int type = getAdapter().getItemViewType(i);
View convertView = mRecycler.get(type);
View v = getAdapter().getView(i, convertView, this);
mRecycler.put(type, v);
v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if(v.getMeasuredHeight() > height) {
height = v.getMeasuredHeight();
}
}
}
if(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
if(maxHeight < height) {
height = maxHeight;
}
}
setMeasuredDimension(getMeasuredWidth(), height);
}
}
@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() {
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) {
Rect viewRect = new Rect();
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if(viewRect.contains((int)e.getX(), (int)e.getY())){
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) {
Rect viewRect = new Rect();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if (viewRect.contains((int) e.getX(), (int) e.getY())) {
if (mOnItemLongClicked != null) {
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
}
};
}
您可以在listview中将数据设置为自定义listadapter。
这是自定义适配器
private class ListAdapter extends ArrayAdapter<bin> { // --CloneChangeRequired
private ArrayList<bin> mList; // --CloneChangeRequired
ImageView img;
TextView title;
String id;
public ListAdapter(Context context, int textViewResourceId,
ArrayList<bin> list) { // --CloneChangeRequired
super(context, textViewResourceId, list);
this.mList = list;
imageLoader = new ImageLoader(YoutubeplayerActivity.this
.getApplicationContext());
}
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
try {
if (view == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.cuslistview, null); // --CloneChangeRequired(list_item)
}
img = (ImageView) view.findViewById(R.id.imageView1);
title = (TextView) view.findViewById(R.id.textView1);
final bin listItem = mList.get(position);
// --CloneChangeRequired
if (listItem != null) {
id = listItem.getId();
imageLoader.DisplayImage(listItem.getThumbnail(), img);
title.setText(listItem.getTitle());
rlv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
}
} catch (Exception e) {
Log.v("log", "" + e.toString());
}
return view;
}
}
您可以在水平列表视图中绑定数据
HorizonatlListView hv = (HorizontalListView) findviewbyId(R.id.hv1);
hv.setadater(new ListAdapter(getApplicationContext,R.id.hv1,ArrayList<bin>));