4

各行の高さが固定されている ListView があります。
すべての行には、いくつかの画像の横に TextView が含まれています。
表示したいテキストが大きすぎる場合があるため、スクロール可能にしたいと考えています。だから私は( AndroidでTextViewをスクロール可能にすることに
基づいて)次の行を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);

  }
}
4

4 に答える 4

14

getLineCountおよびgetLineHieghtを実行し、TextがTextViewよりも大きいかどうかを確認します。

このコードを使用する場合、(boolean)isLarger = trueを指定してTextView以外の場所にタッチすると、listViewをスクロールできます。

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);
于 2013-03-03T19:59:52.430 に答える
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;
    }
于 2011-11-17T07:55:20.040 に答える
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;
  }

}
于 2011-12-09T11:38:49.323 に答える