Android View 不会通过滑动手势滚动,也不会滚动。将 ListView 与 ArrayAdapter 一起使用
Posted
技术标签:
【中文标题】Android View 不会通过滑动手势滚动,也不会滚动。将 ListView 与 ArrayAdapter 一起使用【英文标题】:Android View won't scroll with swipe gesture and won't scroll. Using ListView with ArrayAdapter 【发布时间】:2012-05-30 13:40:45 【问题描述】:我正在为我的ListView
使用自定义ArrayAdapter
。我在左侧有一个CheckBox
,在CheckBox
的右侧有两个TextView
项目,它们相互堆叠。我也在使用自定义的android:listSelector
。
我在 MyActivity
onCreate
方法中将 8 个项目插入到我的自定义 ListView
中。
我可以选择列表中的一行来改变颜色,我还可以选中和取消选中复选框。但是,视图不会响应垂直滑动,当我用手指将鼠标悬停在项目上时,它也不会给项目焦点。如果我同时单击该项目并用另一根手指向下滚动,我可以滚动,但这不是我想要的。我是否以某种方式破坏了垂直滑动手势?
我想指出我的问题中没有 ScrollView
对象。大多数帖子都与将ListView
对象放在ScrollView
中的人有关,反之亦然。
我怀疑我的布局有问题和/或我在布局和代码中分配焦点的方式有问题。
这是我的主要活动代码:
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
public class MyActivity extends Activity
private ListView lv;
private TextView titleDisplay;
private TextView locationDisplay;
private ArrayList<TalkItem> m_talks = null;
private MyListView m_adapter;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.session_view);
lv = (ListView) findViewById(R.id.sessionlist);
titleDisplay = (TextView) findViewById(R.id.sessiontitle);
locationDisplay = (TextView) findViewById(R.id.sessionlocation);
m_talks = new ArrayList<TalkItem>();
this.m_adapter = new MyListView(this, R.layout.sessionlistitem, m_talks);
lv.setAdapter(this.m_adapter);
lv.setOnItemClickListener(new OnItemClickListener()
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
//TODO: do something
);
//set title and location display
titleDisplay.setText("TITLE");
locationDisplay.setText("LOCATION");
m_talks.add(new TalkItem("first1", "last1", false));
m_talks.add(new TalkItem("first2", "last2", false));
m_talks.add(new TalkItem("first3", "last3", false));
m_talks.add(new TalkItem("first4", "last4", false));
m_talks.add(new TalkItem("first5", "last5", false));
m_talks.add(new TalkItem("first6", "last6", false));
m_talks.add(new TalkItem("first7", "last7", false));
m_talks.add(new TalkItem("first8", "last8", false));
public class MyListView extends ArrayAdapter<TalkItem>
private ArrayList<TalkItem> items;
public MyListView(Context context, int textViewResourceId,
ArrayList<TalkItem> items)
super(context, textViewResourceId, items);
this.items = items;
@Override
public View getView(int position, View convertView, ViewGroup parent)
TalkItem talkItem = items.get(position);
CheckBox checkBox;
TextView topText;
TextView bottomText;
if (convertView == null)
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.sessionlistitem, null);
checkBox = (CheckBox) convertView.findViewById(R.id.icon);
topText = (TextView) convertView.findViewById(R.id.toptext);
bottomText = (TextView) convertView.findViewById(R.id.bottomtext);
// Optimization: Tag the row with it's child views, so we don't have to
// call findViewById() later when we reuse the row.
convertView.setTag(new TalkItemViewHolder(checkBox, topText, bottomText));
// If CheckBox is toggled, update the listitem it is tagged with.
checkBox.setOnClickListener( new View.OnClickListener()
public void onClick(View v)
CheckBox cb = (CheckBox) v ;
TalkItem ti = (TalkItem) cb.getTag();
ti.setChecked( cb.isChecked() );
);
// Reuse existing row view
else
// Because we use a ViewHolder, we avoid having to call findViewById().
TalkItemViewHolder viewHolder = (TalkItemViewHolder) convertView.getTag();
checkBox = viewHolder.getCheckBox();
topText = viewHolder.getTopText();
bottomText = viewHolder.getBottomText();
// Tag the CheckBox with the Planet it is displaying, so that we can
// access the planet in onClick() when the CheckBox is toggled.
if(talkItem!=null)
if(checkBox!=null)
checkBox.setTag(talkItem);
// Display item data
checkBox.setChecked( talkItem.isChecked() );
if(topText!=null)
topText.setText(talkItem.getAuthor());
if(bottomText!=null)
bottomText.setText(talkItem.getTitle());
convertView.setBackgroundResource(android.R.color.transparent);
return convertView;
public class TalkItemViewHolder
private CheckBox checkBox;
private TextView topText;
private TextView bottomText;
public TalkItemViewHolder()
public TalkItemViewHolder(CheckBox checkBox, TextView topText, TextView bottomText)
this.checkBox = checkBox;
this.topText = topText;
this.bottomText = bottomText;
public CheckBox getCheckBox()
return checkBox;
public TextView getTopText()
return topText;
public TextView getBottomText()
return bottomText;
public void setCheckBox(CheckBox checkBox)
this.checkBox = checkBox;
public void setTopText(TextView topText)
this.topText = topText;
public void setBottomText(TextView bottomText)
this.bottomText = bottomText;
public class TalkItem
private String title;
private String author;
private boolean checked = false;
public TalkItem()
title = "";
author = "";
public TalkItem(String title, String author, boolean checked)
this.title = title;
this.author = author;
this.checked = checked;
public String getTitle()
return title;
public String getAuthor()
return author;
public void setTitle(String title)
this.title = title;
public void setAuthor(String author)
this.author = author;
public boolean isChecked()
return checked;
public void setChecked(boolean checked)
this.checked = checked;
public void toggleChecked()
checked = !checked;
这是我的主视图的父布局,标题为session_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sessionviewlayout"
android:layout_
android:layout_
android:background="@color/white"
android:orientation="vertical" >
<TextView
android:id="@+id/sessiontitle"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:gravity="center"
android:textSize="20dp" />
<TextView
android:id="@+id/sessionlocation"
android:layout_
android:layout_
android:layout_below="@+id/sessiontitle"
android:gravity="center"
android:textSize="16dp" />
<ListView
android:id="@+id/sessionlist"
android:layout_
android:layout_
android:layout_below="@+id/sessionlocation"
android:cacheColorHint="@color/transparent"
android:descendantFocusability="blocksDescendants"
android:dividerHeight="3.0sp"
android:drawSelectorOnTop="false"
android:listSelector="@drawable/list_selector"
android:minHeight="1in" />
</RelativeLayout>
这是列表中每个项目的布局,标题为sessionlistitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@color/white"
android:padding="2dip" >
<CheckBox
android:id="@+id/icon"
android:layout_
android:layout_
android:layout_gravity="center_vertical"
android:button="@android:drawable/btn_star"
android:focusable="false"
android:padding="10dp" />
<LinearLayout
android:layout_
android:layout_
android:layout_weight="0.99"
android:clickable="false"
android:focusable="false"
android:orientation="vertical" >
<TextView
android:id="@+id/toptext"
android:layout_
android:layout_
android:layout_weight="1"
android:clickable="false"
android:focusable="false"
android:gravity="center_vertical"
android:singleLine="false"
android:textColor="@color/black"
android:textSize="18dp" />
<TextView
android:id="@+id/bottomtext"
android:layout_
android:layout_
android:layout_weight="1"
android:clickable="false"
android:ellipsize="marquee"
android:focusable="false"
android:singleLine="false"
android:textColor="@color/black"
android:textSize="16dp" />
</LinearLayout>
</LinearLayout>
我的自定义 listSelector list_selector.xml
是
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="@drawable/list_selector_pressed" />
<item
android:state_focused="true"
android:drawable="@drawable/list_selector_pressed" />
<item
android:drawable="@android:color/transparent" />
</selector>
list_selector_pressed.xml
是
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/blue"/>
</shape>
strings.xml
是
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World!</string>
<string name="app_name">My APP</string>
<color name="gray">#aaaaaa</color>
<color name="white">#ffffff</color>
<color name="blue">#5BB5D7</color>
<color name="transparent">#00000000</color>
<color name="black">#000000</color>
</resources>
【问题讨论】:
在某处回收的视图中,您的适配器确实有问题,但如果是这样,我看不出在哪里...... 滚动动作是否需要以特定方式启用焦点? 【参考方案1】:ArrayAdapter
需要在添加完所有内容后进行初始化。具体来说,以下几行:
this.m_adapter = new MyListView(this, R.layout.sessionlistitem, m_talks);
lv.setAdapter(this.m_adapter);
应该是 onCreate
方法的最后几行,在所有 m_talks.add(...)
之后。
xml
布局文件没有任何问题。
【讨论】:
【参考方案2】:我相信问题是由于在相对布局中将列表视图高度设置为 wrap_content 引起的。这对于列表视图来说没有什么意义,因为它的内容通常大于它的屏幕高度。一种可能的解决方法是将顶部的 RelativeLayout 更改为 LinearLayout,然后列表视图上的高度设置可以是:
android:layout_
android:layout_weight="1"
这将使用列表视图的所有剩余空间。
【讨论】:
它有什么效果,还是完全一样?您也可以尝试设置一个小的静态高度作为测试,例如 50dp,看看您是否看到任何滚动。如果不是,那么它可能是别的东西。 哎呀,我实际上可以滚动,但不像普通的 listView。我正在使用模拟器,只有在按住单击按钮并扫动手指时才能滚动。默认的 ListView 在屏幕上以扫动的方式滚动。但我的应用程序没有。一个可能相关的问题是,当我的手指悬停在行项目上时,我还希望我的行聚焦并改变颜色。 我编辑了主要条目以重新表述我的问题,即专注于 ListView 项目并使用扫掠动作滚动。以上是关于Android View 不会通过滑动手势滚动,也不会滚动。将 ListView 与 ArrayAdapter 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
识别 UIView 中的滑动手势以使用手势识别器滚动滚动视图