要实现一个像通讯录一样的listview
public class MyDistributor2Activity extends BaseActivity {
@InjectView(R.id.my_distributor_lv)
PinnedHeaderNoScrollListViewTest distributor_lv;
LayoutInflater layoutInflater;
MyDistributor2 MyDistributor2;
DistributorPinnedHeaderAdapter distributorAdapter;
RequestQueue queue;
MyDistributor2 distributor;
// unsorted list items
ArrayList<MyDistributor2> mItems = new ArrayList<MyDistributor2>();
// array list to store section positions
ArrayList<Integer> mListSectionPos;
// array list to store listView data
ArrayList<MyDistributor2> mListItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sec_my_distributor_list2);
ButterKnife.inject(this);
// Array to ArrayList
mListSectionPos = new ArrayList<Integer>();
mListItems = new ArrayList<MyDistributor2>();
queue = VolleyQuery.getQueue(this);
layoutInflater = LayoutInflater.from(this);
getDate("first");
findDistributor();
}
//===查询得到到的数据,删除了部分代码
public void getDate(final String method) {
url = ConfigStr.api_base + "myself/myDistributor";
StringUTF8Request request = new StringUTF8Request(
Request.Method.POST,
url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
dialog.dismiss();
byte[] bytes = Base64.decode(response, Base64.DEFAULT);
String result = new String(bytes);
Log.d("result_add", result);
try {
JSONObject jsonObject = new JSONObject(result);
String json = jsonObject.getString("RS100065");
Gson gson = new Gson();
mItems = gson.fromJson(json, new TypeToken<List<MyDistributor2>>() {
}.getType());
new Poplulate().execute(mItems);
} catch (Exception e) {
/
}
}
},
queue.add(request);
}
private void setAdapter(ArrayList<MyDistributor2> myDistributor2) {
distributorAdapter = new DistributorPinnedHeaderAdapter(MyDistributor2Activity.this, myDistributor2, mListSectionPos);
distributor_lv.setAdapter(distributorAdapter);
}
// sort array and extract sections in background Thread here we use
// AsyncTask
private class Poplulate extends AsyncTask<ArrayList<MyDistributor2>, ArrayList<MyDistributor2>, ArrayList<MyDistributor2>> {
private void showLoading(View contentView) {
contentView.setVisibility(View.GONE);
}
private void showContent(View contentView) {
contentView.setVisibility(View.VISIBLE);
}
private void showEmptyText(View contentView) {
contentView.setVisibility(View.GONE);
}
@Override
protected void onPreExecute() {
showLoading(distributor_lv);
super.onPreExecute();
}
@Override
protected ArrayList<MyDistributor2> doInBackground(ArrayList<MyDistributor2>... params) {
return cacalation(params[0]);
}
@Override
protected void onPostExecute(ArrayList<MyDistributor2> result) {
if (!isCancelled()) {
if (result.size() <= 0) {
showEmptyText(distributor_lv);
} else {
showContent(distributor_lv);
}
setAdapter(result);
}
super.onPostExecute(result);
}
}
public class SortIgnoreCase implements Comparator<MyDistributor2> {
public int compare(MyDistributor2 s1, MyDistributor2 s2) {
return s1.getInvite_code().compareToIgnoreCase(s2.getInvite_code());
}
}
}
public class DistributorPinnedHeaderAdapter extends BaseAdapter implements /*OnScrollListener,*/ IPinnedHeader, Filterable {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SECTION = 1;
private static final int TYPE_MAX_COUNT = TYPE_SECTION + 1;
private static String mem_letter;
private Filter filter;
Context mContext;
LayoutInflater mLayoutInflater;
int mCurrentSectionPosition = 0, mNextSectionPostion = 0;
// array list to store section positions
ArrayList<Integer> mListSectionPos;
ArrayList<MyDistributor2> mListItems;
BottomPopUp bottomPopUp2;
public DistributorPinnedHeaderAdapter(Context context, ArrayList<MyDistributor2> listItems, ArrayList<Integer> listSectionPos) {
this.mContext = context;
this.mListItems = listItems;
this.mListSectionPos = listSectionPos;
mLayoutInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return mListItems.size();
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return !mListSectionPos.contains(position);
}
@Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
@Override
public int getItemViewType(int position) {
return mListSectionPos.contains(position) ? TYPE_SECTION : TYPE_ITEM;
}
@Override
public Object getItem(int position) {
return mListItems.get(position);
}
@Override
public long getItemId(int position) {
return mListItems.get(position).hashCode();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
int type = getItemViewType(position);
switch (type) {
case TYPE_ITEM://内容部分
convertView = mLayoutInflater.inflate(R.layout.sec_my_distributor_list_item, null);
holder.text_name = (TextView) convertView.findViewById(R.id.my_distributor_item_text_name);
holder.text_tel = (TextView) convertView.findViewById(R.id.my_distributor_item_text_tel);
holder.text_mshopname = (TextView) convertView.findViewById(R.id.my_distributor_item_text_mshopname);
break;
case TYPE_SECTION://头部分类部分
convertView = mLayoutInflater.inflate(R.layout.section_row_view, null);
break;
}
convertView.setTag(holder);
} else {
if(convertView.getTag() instanceof ViewHolder){
holder = (ViewHolder) convertView.getTag();
}else{
holder=new ViewHolder();
int type = getItemViewType(position);
switch (type) {
case TYPE_ITEM:
convertView = mLayoutInflater.inflate(R.layout.sec_my_distributor_list_item, null);
holder.text_name = (TextView) convertView.findViewById(R.id.my_distributor_item_text_name);
holder.text_tel = (TextView) convertView.findViewById(R.id.my_distributor_item_text_tel);
holder.text_mshopname = (TextView) convertView.findViewById(R.id.my_distributor_item_text_mshopname);
break;
case TYPE_SECTION:
convertView = mLayoutInflater.inflate(R.layout.section_row_view, null);
break;
}
}
}
//===设置列表内容各项值
MyDistributor2 distributor = mListItems.get(position);//此处无法获得数据,下面的控件无法绑定数据?
holder.text_name.setText(distributor.getStaff_real_name());
holder.text_tel.setText(distributor.getStaff_partner_phonenum());
holder.text_mshopname.setText(distributor.getStaff_departments_name());
return convertView;
}
@Override
public int getPinnedHeaderState(int position) {
if (getCount() == 0 || position < 0 || mListSectionPos.indexOf(position) != -1) {
return PINNED_HEADER_GONE;
}
mNextSectionPostion = getNextSectionPosition(mCurrentSectionPosition);
if (mNextSectionPostion != -1 && position == mNextSectionPostion - 1) {
return PINNED_HEADER_PUSHED_UP;
}
return PINNED_HEADER_VISIBLE;
}
public int getNextSectionPosition(int currentSectionPosition) {
int index = mListSectionPos.indexOf(currentSectionPosition);
if ((index + 1) < mListSectionPos.size()) {
return mListSectionPos.get(index + 1);
}
return mListSectionPos.get(index);
}
public static class ViewHolder {
public TextView textView;
public TextView sub_textView;
TextView text_name;
TextView text_tel;
TextView text_mshopname;
}
}
activity完整代码
public class MyDistributor2Activity extends BaseActivity {
@InjectView(R.id.my_distributor_lv)
PinnedHeaderNoScrollListViewTest distributor_lv;
LayoutInflater layoutInflater;
MyDistributor2 MyDistributor2;
DistributorPinnedHeaderAdapter distributorAdapter;
RequestQueue queue;
MyDistributor2 distributor;
// unsorted list items
ArrayList<MyDistributor2> mItems = new ArrayList<MyDistributor2>();
// array list to store section positions
ArrayList<Integer> mListSectionPos;
// array list to store listView data
ArrayList<MyDistributor2> mListItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sec_my_distributor_list2);
ButterKnife.inject(this);
// Array to ArrayList
mListSectionPos = new ArrayList<Integer>();
mListItems = new ArrayList<MyDistributor2>();
queue = VolleyQuery.getQueue(this);
layoutInflater = LayoutInflater.from(this);
getDate("first");
findDistributor();
}
//===查询得到到的数据,删除了部分代码
public void getDate(final String method) {
url = ConfigStr.api_base + "myself/myDistributor";
StringUTF8Request request = new StringUTF8Request(
Request.Method.POST,
url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
dialog.dismiss();
byte[] bytes = Base64.decode(response, Base64.DEFAULT);
String result = new String(bytes);
Log.d("result_add", result);
try {
JSONObject jsonObject = new JSONObject(result);
String json = jsonObject.getString("RS100065");
Gson gson = new Gson();
mItems = gson.fromJson(json, new TypeToken<List<MyDistributor2>>() {
}.getType());
new Poplulate().execute(mItems);
} catch (Exception e) {
/
}
}
},
queue.add(request);
}
private void setAdapter(ArrayList<MyDistributor2> myDistributor2) {
distributorAdapter = new DistributorPinnedHeaderAdapter(MyDistributor2Activity.this, myDistributor2, mListSectionPos);
distributor_lv.setAdapter(distributorAdapter);
}
// sort array and extract sections in background Thread here we use
// AsyncTask
private class Poplulate extends AsyncTask<ArrayList<MyDistributor2>, ArrayList<MyDistributor2>, ArrayList<MyDistributor2>> {
private void showLoading(View contentView) {
contentView.setVisibility(View.GONE);
}
private void showContent(View contentView) {
contentView.setVisibility(View.VISIBLE);
}
private void showEmptyText(View contentView) {
contentView.setVisibility(View.GONE);
}
@Override
protected void onPreExecute() {
showLoading(distributor_lv);
super.onPreExecute();
}
@Override
protected ArrayList<MyDistributor2> doInBackground(ArrayList<MyDistributor2>... params) {
return cacalation(params[0]);
}
@Override
protected void onPostExecute(ArrayList<MyDistributor2> result) {
if (!isCancelled()) {
if (result.size() <= 0) {
showEmptyText(distributor_lv);
} else {
showContent(distributor_lv);
}
setAdapter(result);
}
super.onPostExecute(result);
}
}
public class SortIgnoreCase implements Comparator<MyDistributor2> {
public int compare(MyDistributor2 s1, MyDistributor2 s2) {
return s1.getInvite_code().compareToIgnoreCase(s2.getInvite_code());
}
}
private ArrayList<MyDistributor2> cacalation(ArrayList<MyDistributor2>... params) {
ArrayList<MyDistributor2> myDistributor2 = new ArrayList<>();
mListSectionPos.clear();
ArrayList<MyDistributor2> items = params[0];
if (mItems.size() > 0) {
// NOT forget to sort array
Collections.sort(items, new SortIgnoreCase());
String prev_section = "";
for (MyDistributor2 current_item : items) {// Invite_code--首字母
String current_section = current_item.getInvite_code().toUpperCase(Locale.getDefault());
if (!prev_section.equals(current_section)) {
MyDistributor2 myDistributor2_test = new MyDistributor2();
myDistributor2_test.setInvite_code(current_section);
myDistributor2.add(myDistributor2_test);
myDistributor2.add(current_item);
// array list of section positions
mListSectionPos.add(myDistributor2.indexOf(myDistributor2_test));
prev_section = current_section;
} else {
myDistributor2.add(current_item);
}
}
}
return myDistributor2;
}
}
你说得获取不到数据是什么情况?数组越界?空指针?还是根本没走到那一步?
mItems = gson.fromJson(json, new TypeToken>() {}.getType());你遍历一下mitems里面的元素是否为空值
这是错误日志,我打印了 mListItems.get(position),它获取到的是个空值,
java.lang.NullPointerException
at com.bkrtrip.lxb.adapter.my.DistributorPinnedHeaderAdapter.getView(DistributorPinnedHeaderAdapter.java:246)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
at android.widget.AbsListView.obtainView(AbsListView.java:2124)
at android.widget.ListView.makeAndAddView(ListView.java:1787)
at android.widget.ListView.fillDown(ListView.java:675)
at android.widget.ListView.fillFromTop(ListView.java:735)
at android.widget.ListView.layoutChildren(ListView.java:1640)
at android.widget.AbsListView.onLayout(AbsListView.java:1954)
at com.bkrtrip.lxb.view.selectlistview.PinnedHeaderNoScrollListViewTest.onLayout(PinnedHeaderNoScrollListViewTest.java:150)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at me.imid.swipebacklayout.lib.SwipeBackLayout.onLayout(SwipeBackLayout.java:386)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11314)
at android.view.ViewGroup.layout(ViewGroup.java:4234)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1496)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2449)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4430)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:813)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:580)
at dalvik.system.NativeStart.main(Native Method)
PinnedHeaderNoScrollListViewTest这是我用到的带有头部分类效果的listview,报错的代码是再onlyout方法中的super.onLayout(changed, left, top, right, bottom);
/*
* Copyright (C) 2010 The Android Open Source Project
*
* 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.
*/
// modified by @author Bhavya Mehta
package com.bkrtrip.lxb.view.selectlistview;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.bkrtrip.lxb.R;
import com.bkrtrip.lxb.adapter.apply.CustomerPinnedHeaderAdapter;
import com.bkrtrip.lxb.adapter.my.DistributorPinnedHeaderAdapter;
import com.bkrtrip.lxb.view.selectlistview.inter.IIndexBarFilter;
import com.bkrtrip.lxb.view.selectlistview.inter.IPinnedHeader;
/*
* A ListView that maintains a header pinned at the top of the list. The
* pinned header can be pushed up and dissolved as needed.
*/
public class PinnedHeaderNoScrollListViewTest extends ListView implements IIndexBarFilter {
// interface object that configure pinned header view position in list view
IPinnedHeader mAdapter;
// view objects
View mHeaderView,mIndexBarView,mPreviewTextView;
// flags that decide view visibility
boolean mHeaderVisibility=false;
boolean mPreviewVisibility=false;
// initially show index bar view with it's content
boolean mIndexBarVisibility=true;
// context object
Context mContext;
// view height and width
int mHeaderViewWidth,
mHeaderViewHeight,
mIndexBarViewWidth,
mIndexBarViewHeight,
mIndexBarViewMarginTop,
mIndexBarViewMargin,
mPreviewTextViewWidth,
mPreviewTextViewHeight;
// touched index bar Y axis position used to decide preview text view position
float mIndexBarY;
public PinnedHeaderNoScrollListViewTest(Context context) {
super(context);
this.mContext = context;
}
public PinnedHeaderNoScrollListViewTest(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
public PinnedHeaderNoScrollListViewTest(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
}
public View getmIndexBarView() {
return mIndexBarView;
}
@Override
public void setAdapter(ListAdapter adapter) {
this.mAdapter = (DistributorPinnedHeaderAdapter)adapter;
super.setAdapter(adapter);
}
public void setPinnedHeaderView(View headerView) {
this.mHeaderView = headerView;
// Disable vertical fading when the pinned header is present
// TODO change ListView to allow separate measures for top and bottom fading edge;
// in this particular case we would like to disable the top, but not the bottom edge.
if (mHeaderView != null) {
setFadingEdgeLength(0);
}
}
public void setIndexBarView(View indexBarView) {
mIndexBarViewMargin = (int)mContext.getResources().getDimension(R.dimen.index_bar_view_margin);
mIndexBarViewMarginTop=(int)mContext.getResources().getDimension(R.dimen.index_bar_view_margin2);
this.mIndexBarView = indexBarView;
}
public void setPreviewView(View previewTextView) {
this.mPreviewTextView=previewTextView;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mHeaderView != null) {
measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);
mHeaderViewWidth = mHeaderView.getMeasuredWidth();
mHeaderViewHeight = mHeaderView.getMeasuredHeight();
}
if (mIndexBarView != null && mIndexBarVisibility) {
measureChild(mIndexBarView, widthMeasureSpec, heightMeasureSpec);
mIndexBarViewWidth = mIndexBarView.getMeasuredWidth();
mIndexBarViewHeight = mIndexBarView.getMeasuredHeight();
}
if (mPreviewTextView != null && mPreviewVisibility) {
measureChild(mPreviewTextView, widthMeasureSpec, heightMeasureSpec);
mPreviewTextViewWidth = mPreviewTextView.getMeasuredWidth();
mPreviewTextViewHeight = mPreviewTextView.getMeasuredHeight();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mHeaderView != null) {
mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
configureHeaderView(getFirstVisiblePosition());
}
if (mIndexBarView != null && mIndexBarVisibility) {
mIndexBarView.layout(getMeasuredWidth()- mIndexBarViewMargin - mIndexBarViewWidth, 0
, getMeasuredWidth()- mIndexBarViewMargin, getMeasuredHeight());
}
if (mPreviewTextView != null && mPreviewVisibility) {
mPreviewTextView.layout(mIndexBarView.getLeft()-mPreviewTextViewWidth, (int)mIndexBarY-(mPreviewTextViewHeight/2)
, mIndexBarView.getLeft(), (int)(mIndexBarY-(mPreviewTextViewHeight/2))+mPreviewTextViewHeight);
}
}
public void setIndexBarVisibility(Boolean isVisible) {
if(isVisible) {
mIndexBarVisibility=true;
}
else {
mIndexBarVisibility=false;
}
}
private void setPreviewTextVisibility(Boolean isVisible) {
if(isVisible) {
mPreviewVisibility=true;
}
else {
mPreviewVisibility=false;
}
}
public void configureHeaderView(int position) {
if (mHeaderView == null) {
return;
}
int state = mAdapter.getPinnedHeaderState(position);
switch (state) {
case IPinnedHeader.PINNED_HEADER_GONE:
mHeaderVisibility = false;
break;
case IPinnedHeader.PINNED_HEADER_VISIBLE:
if (mHeaderView.getTop() != 0) {
mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
}
mAdapter.configurePinnedHeader(mHeaderView, position);
mHeaderVisibility = true;
break;
case IPinnedHeader.PINNED_HEADER_PUSHED_UP:
View firstView = getChildAt(0);
int bottom = firstView.getBottom();
// int itemHeight = firstView.getHeight();
int headerHeight = mHeaderView.getHeight();
int y;
if (bottom < headerHeight) {
y = (bottom - headerHeight);
}
else {
y = 0;
}
if (mHeaderView.getTop() != y) {
mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);
}
mAdapter.configurePinnedHeader(mHeaderView, position);
mHeaderVisibility = true;
break;
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);// draw list view elements (zIndex == 1)
if (mHeaderView != null && mHeaderVisibility) {
drawChild(canvas, mHeaderView, getDrawingTime()); // draw pinned header view (zIndex == 2)
}
if (mIndexBarView != null && mIndexBarVisibility) {
drawChild(canvas, mIndexBarView, getDrawingTime()); // draw index bar view (zIndex == 3)
}
if (mPreviewTextView != null && mPreviewVisibility) {
drawChild(canvas, mPreviewTextView, getDrawingTime()); // draw preview text view (zIndex == 4)
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mIndexBarView != null && ((IndexBarNoScrollView)mIndexBarView).onTouchEvent(ev)) {
setPreviewTextVisibility(true);
return true;
}
else {
setPreviewTextVisibility(false);
return super.onTouchEvent(ev);
}
}
@Override
public void filterList(float indexBarY, int position,String previewText) {
this.mIndexBarY=indexBarY;
if(mPreviewTextView instanceof TextView)
((TextView)mPreviewTextView).setText(previewText);
setSelection(position);
}
}
这个跟onlayout没半毛钱关系,出错的是你的数据,如果我没猜错的话你的list里面存的都是null,也就是说你解析数据的时候就已经错了,看看自己的数据和数据的解析方法吧
还有你解析错误的地方既然捕捉的异常你至少应该打印点啥,不应该就这么屏蔽掉