RT:
先上图
在Hot Keywords下面实现的是自动换行的效果
直接附上代码
如下
自定义布局CustomListView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
public class CustomListView extends RelativeLayout {
private String TAG = CustomListView.class.getSimpleName();
private CustomAdapter myCustomAdapter;
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean arg0, int argLeft, int argTop, int argRight, int argBottom) {
Log.i(TAG, "L:"+argLeft+" T:"+argTop+" R:"+argRight+" B:"+argBottom);
final int count = getChildCount();
int row=0;
int lengthX=0;
int lengthY=0;
for(int i=0;i<count;i++){
final View child = this.getChildAt(i);
int width = child.getMeasuredWidth();
int height = child.getMeasuredHeight();
if(lengthX == 0){
lengthX += width;
}else{
lengthX += (width+getDividerWidth());
}
if((i == 0 && lengthX<=argRight)){
lengthY += height;
}
if(lengthX>argRight){
lengthX = width;
lengthY += getDividerHeight()+height;
row++;
child.layout(lengthX-width, lengthY-height, lengthX, lengthY);
}else{
child.layout(lengthX-width, lengthY-height, lengthX, lengthY);
}
}
android.view.ViewGroup.LayoutParams lp = CustomListView.this.getLayoutParams();
lp.height = lengthY;
CustomListView.this.setLayoutParams(lp);
if(isAddChildType()){
new Thread(new RefreshCustomThread()).start();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private static boolean addChildType;
final static boolean isAddChildType() {
return addChildType;
}
public static void setAddChildType(boolean addChildType) {
CustomListView.addChildType = addChildType;
}
private int dividerHeight = 0;
final int getDividerHeight() {
return dividerHeight;
}
public void setDividerHeight(int dividerHeight) {
this.dividerHeight = dividerHeight;
}
private int dividerWidth = 0;
final int getDividerWidth() {
return dividerWidth;
}
public void setDividerWidth(int dividerWidth) {
this.dividerWidth = dividerWidth;
}
public void setAdapter(CustomAdapter adapter){
this.myCustomAdapter = adapter;
setAddChildType(true);
adapter.notifyCustomListView(CustomListView.this);
}
/**
*
* @param listener
*/
public void setOnItemClickListener(OnItemClickListener listener){
myCustomAdapter.setOnItemClickListener(listener);
}
/**
* Corresponding Item long click event
*
* @param listener
*/
public void setOnItemLongClickListener(OnItemLongClickListener listener){
myCustomAdapter.setOnItemLongClickListener(listener);
}
private final Handler handler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
try{
if(msg.getData().containsKey("getRefreshThreadHandler")){
setAddChildType(false);
myCustomAdapter.notifyCustomListView(CustomListView.this);
}
}catch(Exception e){
Log.w(TAG, e);
}
}
};
private final class RefreshCustomThread implements Runnable{
@Override
public void run() {
Bundle b = new Bundle();
try{
Thread.sleep(50);
}catch(Exception e){
}finally{
b.putBoolean("getRefreshThreadHandler", true);
sendMsgHanlder(handler, b);
}
}
}
private final void sendMsgHanlder(Handler handler,Bundle data){
Message msg = handler.obtainMessage();
msg.setData(data);
handler.sendMessage(msg);
}
}
|
CustomAdapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
public class CustomAdapter{
private String TAG = CustomAdapter.class.getSimpleName();
private View myView;
private ViewGroup myViewGroup;
private CustomListView myCustomListView;
private OnItemClickListener listener;
private OnItemLongClickListener longListener;
public int getCount() {
return 0;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(final int position, View convertView, ViewGroup parent) {
return null;
}
/**
*
* Add all the View controls to the custom SexangleViewList
* When you use this SexangleViewList should be instantiated first and then call
* Because here is not intercept and throw such as null pointer exception
* The name is called mySexangleView View passed in must be empty
* Of course the ViewGroup transfer time must also be empty
*
*/
private final void getAllViewAddSexangle(){
this.myCustomListView.removeAllViews();
for(int i = 0 ; i < getCount() ; i++){
View viewItem = getView(i, this.myView, this.myViewGroup);
this.myCustomListView.addView(viewItem,i);
}
}
/**
*
* The refresh SexangleListView interface
* Here is set to True representative will execute reset CustomListView twice
* This method is called before, please first instantiation mySexangleListView
* Otherwise, this method in redraw CustomListView abnormal happens
*
*/
public void notifyDataSetChanged(){
CustomListView.setAddChildType(true);
notifyCustomListView(this.myCustomListView);
}
/**
* Redraw the Custom controls for the first time, you should invoke this method
* In order to ensure that each load data do not repeat to get rid of the
* custom of the ListView all View objects
* The following will be set up to monitor events as controls
* First load regardless whether OnItemClickListener and OnItemLongClickListener is NULL,
* they do not influence events Settings
*
* @param formateList
*/
public void notifyCustomListView(CustomListView formateList){
this.myCustomListView = formateList;
myCustomListView.removeAllViews();
getAllViewAddSexangle();
setOnItemClickListener(listener);
setOnItemLongClickListener(longListener);
}
/**
* Set the click event of each View, external can realize the interface for your call
*
* @param listener
*/
public void setOnItemClickListener(final OnItemClickListener listener){
this.listener = listener;
for(int i = 0; i < myCustomListView.getChildCount(); i++){
final int parame = i;
View view = myCustomListView.getChildAt(i);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "当前Item的值 : "+parame);
listener.onItemClick(null, v, parame, getCount());
}
});
}
}
/**
* Set each long press event, the View outside can realize the interface for your call
*
* @param listener
*/
public void setOnItemLongClickListener(final OnItemLongClickListener listener){
this.longListener = listener;
for(int i = 0; i < myCustomListView.getChildCount(); i++){
final int parame = i;
View view = myCustomListView.getChildAt(i);
view.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
listener.onItemLongClick(null, v, parame, getCount());
return true;
}
});
}
}
}
|
CustomListView需要用到的适配器MainSexangleAdapter需要继承上面的CustomAdapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
public class MainSexangleAdapter extends CustomAdapter {
private List<String> list;
private Context con;
private LayoutInflater inflater;
public MainSexangleAdapter(Context context, List<String> list) {
this.con = context;
this.list = list;
inflater = LayoutInflater.from(con);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh = null;
if(convertView == null){
vh = new ViewHolder();
convertView = inflater.inflate(R.layout.auto_adapter, null);
vh.tv = (TextView) convertView.findViewById(R.id.adapter_text);
convertView.setTag(vh);
}else{
vh = (ViewHolder) convertView.getTag();
}
String str = list.get(position);
vh.tv.setText(str);
return convertView;
}
public class ViewHolder{
public TextView tv;
}
}
|
然后是两个接口OnItemClickListener
1 2 3 4 |
public interface OnItemClickListener {
public void onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3);
}
|
OnItemLongClickListener
1 2 3 4 |
public interface OnItemLongClickListener {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,int arg2, long arg3);
}
|
以上为java代码
所需要的布局文件 只要一个放入CustomListView 的xml
和一个adapter的xml;可以自己去写。
在MainActivity中实现方法即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public class AutoActivity extends Activity{
private String TAG = AutoActivity.class.getSimpleName();
private CustomListView lv;
private List<String> list = null;
private MainSexangleAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.auto);
CustomListView lv = (CustomListView) findViewById(R.id.sexangleView);
setData();
ShowSexangleListView();
}
private void ShowSexangleListView(){
adapter = new MainSexangleAdapter(this, list);
lv.setDividerHeight(10);
lv.setDividerWidth(10);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Toast.makeText(AutoActivity.this, "点击了 : "+arg2, 300).show();
}
});
}
private void setData(){
list = new ArrayList<String>();
list.add("Powerball");
list.add("Lil Kim Pregnant");
list.add("Nicki Minaj");
list.add("MTA");
list.add("House of Cards");
list.add("Valentine's Day");
}
}
|
以上即能实现 所需要的自动换行效果
注意 :如果布局文件 对这个自定义布局做了padding或者marging的话 CustomListView 当中的 argRight需要相应的减去你得设置。不然会有偏差。自己debug可以测试出来的!
Pass:以上查阅了很多网上资料,可是效果都不是很理想,后面联系到http://blog.csdn.net/alovebtoc/article/details/17244111博客的博主,在他的帮助下实现了以上效果,再次非常感谢对方