androud ListView 仿 IPhone UITable Title效果(有Title数据不更改缺陷。&待续)

来源:互联网 发布:软件设计师难不难 编辑:程序博客网 时间:2024/05/20 19:29


android ListView的分组实现方式参照了以下博客链接的实现方式在此基础上修改。

http://wang-peng1.iteye.com/blog/578411


类似实现方法可参照源码----通讯录-PinnedHeaderListView

以下实现方法缺点:

1、Title透明向上时上一分组的最后一个Cell会被看见。

2、SectionedAdapter的实现方式对于ListView中的Cell重用机制处理的不是很好。

3、Title的实现方式是以Bitmap形式绘制,N多个大Title载入后不能保证不内存溢出。


使用AbsoluteLayout+LIstView实现可能更简便。


SectionedAdapter继承自BaseAdapter 实现了多个Adapted的分组。

以上博客地址在滑动后出现分组Title和Cell的布局加载错误。在此基础上做了以下修改。

abstract public class SectionedAdapter extends BaseAdapter {abstract protected View getHeaderView(String caption,int index,View convertView,ViewGroup parent);private List<Section> sections=new ArrayList<Section>();private static int TYPE_SECTION_HEADER=0;private Context mContext;public SectionedAdapter(Context mContext) {super();this.mContext = mContext;}public void addSection(String caption, Adapter adapter, int res) {sections.add(new Section(caption, adapter, res));}@Overridepublic Object getItem(int position) {for (Section section : this.sections) {if (position==0) {return(section);}int size=section.adapter.getCount()+1;if (position<size) {return(section.adapter.getItem(position-1));}position-=size;}return(null);}@Overridepublic int getCount() {int total=0;for (Section section : this.sections) {total+=section.adapter.getCount()+1; // add one for header}return(total);}@Overridepublic int getViewTypeCount() {int total=1;// one for the header, plus those from sectionsfor (Section section : this.sections) {total+=section.adapter.getViewTypeCount();}return(total);}@Overridepublic int getItemViewType(int position) {int typeOffset=TYPE_SECTION_HEADER+1;// start counting from herefor (Section section : this.sections) {if (position==0) {return(TYPE_SECTION_HEADER);}int size=section.adapter.getCount()+1;if (position<size) {return(typeOffset+section.adapter.getItemViewType(position-1));}position-=size;typeOffset+=section.adapter.getViewTypeCount();}return(-1);}public boolean areAllItemsSelectable() {return(false);}@Overridepublic boolean isEnabled(int position) {return(getItemViewType(position)!=TYPE_SECTION_HEADER);}@Overridepublic View getView(int position, View convertView,ViewGroup parent) {int sectionIndex=0;for (Section section : this.sections) {if (position==0) {return(getHeaderView(section.caption, sectionIndex,convertView, parent));}int size=section.adapter.getCount()+1;if (position<size) {if(convertView!=null && convertView.getTag().equals(section.res))convertView = section.adapter.getView(position-1,convertView,parent);else {convertView = LayoutInflater.from(mContext).inflate(section.res, null);convertView = section.adapter.getView(position-1,convertView,parent);convertView.setTag(section.res);}return(convertView);}position-=size;sectionIndex++;}return(null);}@Overridepublic long getItemId(int position) {return(position);}class Section {String caption;Adapter adapter;int res;Section(String caption, Adapter adapter,int res) {this.caption=caption;this.adapter=adapter;this.res = res;}}}


StartAct 程序入口在其中实现了SectionedAdapter对Title的加载

public class StartAct extends Activity {    /** Called when the activity is first created. */SectionedAdapter sectionAdapter;UITableView tableView;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//      数据导入        sectionAdapter = new SectionedAdapter(this) {@Overrideprotected View getHeaderView(String caption, int index, View convertView,ViewGroup parent) {// TODO Auto-generated method stubTextView result=(TextView)convertView;if (result==null || convertView.getTag()!=null && !convertView.getTag().equals("title")) {result=(TextView)getLayoutInflater().inflate(R.layout.header, null);result.setTag("title");}result.setText(caption);return result;}};//tableView = new UITableView(this);this.setContentView(tableView);tableView.setAdapter(sectionAdapter);for(int i =0;i<10;i++) {ArrayAdapter<String> a = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[] {"1","1","1","1","1"});sectionAdapter.addSection("Title"+i, a,android.R.layout.simple_list_item_1);}    }    }

UITableView 继承自ListView。实现OnScrollListener

在父类的dispatchDraw方法中重绘Title

public class UITableView extends ListView implements OnScrollListener {private static final int MAX_ALPHA = 255;private TreeMap<String, Bitmap> titlemap;private List<String> keylist;private int Section;private View mHeadView;private Paint mPaint;int titledy;public UITableView(Context context) {super(context);// TODO Auto-generated constructor stubSection = 0;titlemap = new TreeMap<String, Bitmap>();keylist = new ArrayList<String>();mPaint = new Paint();this.setVerticalFadingEdgeEnabled(false);this.setOnScrollListener(this);}/* * (non-Javadoc) *  * @see android.widget.ListView#dispatchDraw(android.graphics.Canvas) */@Overrideprotected void dispatchDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.dispatchDraw(canvas);if(mHeadView == null) return;canvas.save();int childid = this.getPositionForView(this.getChildAt(0));String titlekey = "";String key = "" + Section;titledy = 0;mPaint.setAlpha(MAX_ALPHA);Log.d("TAG", "childid:" + childid + "----Section:" + Section+"-----index:"+keylist.indexOf(key));if (childid < Section) {if (keylist.contains(key) && keylist.indexOf(key) > 0) {titlekey = keylist.get(keylist.indexOf(key)-1);} else {titlekey = keylist.get(0);}//标签移动计算if(mHeadView.getTop()<=mHeadView.getHeight()) {titledy-=(mHeadView.getHeight()-mHeadView.getTop());int alpha = (int) (MAX_ALPHA*(mHeadView.getTop()*1.0f/mHeadView.getHeight()));mPaint.setAlpha(alpha);}}else if(childid == Section) {titlekey = keylist.get(keylist.indexOf(key));titledy = 0;}else if(childid >Section && keylist.indexOf(key)== keylist.size()-1){titlekey = keylist.get(keylist.size()-1);titledy = 0;}if (titlemap.get(titlekey) != null)canvas.drawBitmap(titlemap.get(titlekey), 0, titledy, mPaint);canvas.restore();}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {// TODO Auto-generated method stub}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// TODO Auto-generated method stubfor (int i = 0; i < visibleItemCount; i++) {Object obj = this.getAdapter().getItem(firstVisibleItem + i);if (obj.getClass() == SectionedAdapter.Section.class) {if (titlemap.get("" + (firstVisibleItem + i)) == null) {this.getChildAt(i).setDrawingCacheEnabled(true);Bitmap bmp = Bitmap.createBitmap(this.getChildAt(i).getDrawingCache());if (!bmp.isRecycled()) {titlemap.put("" + (firstVisibleItem + i), bmp);if (!keylist.contains("" + (firstVisibleItem + i))) {keylist.add("" + (firstVisibleItem + i));}}this.getChildAt(i).setDrawingCacheEnabled(false);}Section = firstVisibleItem + i;mHeadView = this.getChildAt(i);break;}}}}



原创粉丝点击