最近在做項目,需要在ListView中點選item展開一個固定高度的EditText,不能編輯,如果内容過多就需要滾動.但是發現EditText的滾動跟ListView的滾動沖突了
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DNyITO1QTNwEzMyATM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
在這裡我參考了這個文章: http://blog.csdn.net/goodlixueyong/article/details/41172465
原理是當點到EditText上的時候,就讓EditText擷取焦點,屏蔽Listview的滾動,當手指離開EditText的時候,恢複ListView的滾動.但是這會有個問題,影響了使用者體驗,就是如果内容不多的時候,EditText還是那麼高,點在上面的時候,就無法讓ListView滾動的.是以這裡我就給每個EditText加上一個判斷内容高度的處理.如果内容過高,EditText可滾動的時候,就按上去就滾動EditText,如果内容不多或者按在EditText外面的時候,就滾動ListView.
以下是關鍵代碼:
ViewTreeObserver vto = holder.et_comment.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
holder.et_comment.getViewTreeObserver().removeGlobalOnLayoutListener(this);
editText_height=holder.et_comment.getHeight();
if(line_height==0){
Paint textPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(holder.et_comment.getTextSize());
LogUtil.v(TAG, "editText_height:"+editText_height+" text size:"+holder.et_comment.getTextSize());
FontMetrics fontMetrics = textPaint.getFontMetrics();
line_height=(int) Math.abs(fontMetrics.top-fontMetrics.bottom);
}
int contentHeight=holder.et_comment.getLineCount()*line_height;
if(contentHeight>editText_height){
editTextTouchList.put(position, true);
LogUtil.e(TAG, "contentHeight:"+contentHeight+" pos:"+position+" line:"+holder.et_comment.getLineCount()+" 要控 制");
}else{
editTextTouchList.put(position, false);
LogUtil.v(TAG, "editText_height:"+editText_height+" pos:"+position+" line:"+holder.et_comment.getLineCount()+" 不用控制----");
}
}
});
以上是點選item,展開EditText的時候,等EditText繪制好了,擷取他的高度.另外還要根據目前字型,來擷取每一行的高度,乘以行數,如果内容高于EditText的高度,就用一個清單把是否可以滾動的辨別儲存起來.P.S:這裡沒用edittext.getLineHeight這個更簡單的方法是因為他擷取出來的高度不準,有一點點偏差.有興趣的朋友們可以自己試試就知道了.
holder.et_comment.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.et_comment:
if(editTextTouchList.containsKey(position)){
if(editTextTouchList.get(position)){
v.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
}
}
}
return false;
}
});
然後是重寫Edittext的onTouch事件,如果這個EditText被記錄為需要滾動的,就把他的parent(就是listview)的touch事件給先攔截處理了.如果手指up了,就讓他恢複原狀.
這樣的話就可以讓過多内容的EditText滾動,按着内容不多的EditText的時候,就照樣可以滾動ListView了.
*****忘了補充說明下,由于重寫了onTouch事件,在某些機型上可能會影響長按出那個"複制","黏貼"的選項.這個要留意.由于我的需求是不能編輯,是以沒影響,如果你的需要編輯,這個可能要考慮下怎麼改******