我有一个ListView,每行的高度都是固定的 每行包含一些TextView旁边的文本 有时,我想要显示的文字太大,因此我想让它可滚动 所以我添加了(基于Making TextView scrollable on Android)以下行到我的TextView
text.setMaxLines(5);
text.setVerticalScrollBarEnabled(true);
text.setMovementMethod(ScrollingMovementMethod.getInstance());
如果我单独使用TextView,但是当我将TextView放在ListView中时,这可以正常工作:
一旦我进行垂直滚动,事件似乎被ListView消耗。
关于如何使这项工作的任何建议?
下面添加了完整(测试)活动(没有layout.xml)
public class TestScrollableTextView extends Activity
{
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
//add a ListView
ListView list = new ListView(this);
layout.addView(list);
list.setAdapter(new BaseAdapter()
{
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
TextView text = new TextView(TestScrollableTextView.this);
String s = "";
//add 10 lines of text, all but first are indented
for (int i = 0; i < 10; i++)
{
if(i>0) s+="\t";
s += "position "+position+"; line="+i+"\n";
}
text.setText(s);
text.setMaxLines(5);
text.setVerticalScrollBarEnabled(true);
text.setMovementMethod(ScrollingMovementMethod.getInstance());
return text;
}
@Override
public long getItemId(int position)
{
return 0;
}
@Override
public Object getItem(int position)
{
return null;
}
@Override
public int getCount()
{
return 20;
}
});
setContentView(layout);
}
}
答案 0 :(得分:13)
getLineCount和getLineHieght并检查Text是否大于TextView。
如果您使用此代码,可以通过触摸TextView以外的任何位置来滚动listView,其中(boolean)isLarger = true。
text.setText(s);
text.setMaxLines(100);
text.setVerticalScrollBarEnabled(true);
text.setMovementMethod(new ScrollingMovementMethod());
OnTouchListener listener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean isLarger;
isLarger = ((TextView) v).getLineCount()
* ((TextView) v).getLineHeight() > v.getHeight();
if (event.getAction() == MotionEvent.ACTION_MOVE
&& isLarger) {
v.getParent().requestDisallowInterceptTouchEvent(true);
} else {
v.getParent().requestDisallowInterceptTouchEvent(false);
}
return false;
}
};
text.setOnTouchListener(listener);
答案 1 :(得分:0)
我可以通过创建ListView的子类并覆盖onTouchEvent来完成这项工作,如下所示:
- 我首先检查MotionEvent是否在childView中
- 如果是,我打电话给孩子的onTouchEvent
这似乎是非常基本的框架功能,所以我很惊讶这不是由ListView本身处理的。我错过了什么吗?
@Override
public boolean onTouchEvent(MotionEvent event)
{
//find correct child
View theChild = null;
boolean handled = false;
for (int i = 0; i < getChildCount(); i++)
{
View child = getChildAt(i);
Rect rect = new Rect();
child.getDrawingRect(rect);
offsetDescendantRectToMyCoords(child, rect);
if(rect.contains((int)event.getX(), (int)event.getY()))
{
theChild = child;
}
}
if(theChild!=null)
{
handled = theChild.onTouchEvent(event);
}
if(!handled) handled = super.onTouchEvent(event);
return handled;
}
答案 2 :(得分:0)
更好的方法是按如下方式创建自己的MyTextView并调用requestDisallowInterceptTouchEvent。通过这样做,您向列表视图指示它不应该拦截事件。
class MyTextView extends TextView
{
public MyTextView(Context context)
{
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean dispatchTouchEvent(MotionEvent event)
{
boolean ret;
ret = super.dispatchTouchEvent(event);
if(ret)
{
list.requestDisallowInterceptTouchEvent(true);
}
return ret;
}
}
答案 3 :(得分:0)
使用此自定义来解决您的问题。
public class ScrollableListView extends ListView {
public ScrollableListView(Context context) {
super(context);
}
public ScrollableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false");
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false");
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false");
return false;
default:
Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action);
break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction());
return true;
}
}