我使用自定义用户率对传感器(使ListView繁忙)进行采样,并在列表视图中显示值,因此我有一个自定义列表视图,其中包含3个textview(对于x,y和z值)和一个微调器。
我的布局是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:minWidth="140dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="X:"
android:id="@+id/tvX"
android:focusable="false"
android:focusableInTouchMode="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Y:"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="@+id/tvY" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Z:"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="@+id/tvZ" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="30dp">
<Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:id="@+id/spinner"/>
</LinearLayout>
</LinearLayout>
我将此代码用作适配器:
public class customListView extends BaseAdapter
{
public Activity context;
ArrayList<MyActivity.SensorProperties> sensorPropertieses;
public String[] spinnerValues;
public LayoutInflater inflater;
public customListView(Activity context, ArrayList<MyActivity.SensorProperties> sensorPropertieses, String[] spinnerArray)
{
super();
this.context = context;
this.sensorPropertieses = sensorPropertieses;
spinnerValues = spinnerArray;
this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return sensorPropertieses.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
class ViewHolder
{
TextView Xvalue, Yvalue, Zvalue;
Spinner spinner;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup)
{
ViewHolder holder;
if (view == null)
{
holder = new ViewHolder();
view = inflater.inflate(R.layout.custom_layout, null);
holder.Xvalue = (TextView) view.findViewById(R.id.tvX);
holder.Yvalue = (TextView) view.findViewById(R.id.tvY);
holder.Zvalue = (TextView) view.findViewById(R.id.tvZ);
holder.spinner = (Spinner) view.findViewById(R.id.spinner);
// populate spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
(view.getContext(), android.R.layout.simple_spinner_item, spinnerValues);
holder.spinner.setAdapter(dataAdapter);
view.setTag(holder);
}
else
holder = (ViewHolder) view.getTag();
// update sensor values
holder.Xvalue.setText(String.valueOf("X: " + sensorPropertieses.get(i).x));
holder.Yvalue.setText(String.valueOf("Y: " + sensorPropertieses.get(i).y));
holder.Zvalue.setText(String.valueOf("Z: " + sensorPropertieses.get(i).z));
return view;
}
}
我的主要活动代码是(布局只包含一个按钮和列表视图):
public class MyActivity extends Activity implements SensorEventListener
{
public class SensorProperties
{
public float x = 0, y = 0, z = 0;
}
ListView listView;
ArrayList<SensorProperties> sensorPropertieses = new ArrayList<SensorProperties>();
customListView adapter;
SensorManager sensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// let's work only on two nodes
sensorPropertieses.add(new SensorProperties());
sensorPropertieses.add(new SensorProperties());
listView = (ListView) findViewById(R.id.listView);
String[] spinnerValues = new String[] {"A", "B", "C"};
adapter = new customListView(MyActivity.this, sensorPropertieses, spinnerValues);
listView.setAdapter(adapter);
Button btnRegister = (Button) findViewById(R.id.buRegister);
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view)
{
RegisterToSensors();
}
});
}
void RegisterToSensors()
{
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent)
{
SensorProperties tmp = new SensorProperties();
tmp.x = sensorEvent.values[0];
tmp.y = sensorEvent.values[1];
tmp.z = sensorEvent.values[2];
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
sensorPropertieses.set(0, tmp);
else
sensorPropertieses.set(1, tmp);
adapter.notifyDataSetChanged();
}
///...
}
问题:我应该如何使用ListView包含TextView和Spinner,虽然我更新了TextView频率,却没有丢失微调器焦点?
修改
由于mmlooloo
评论,我更改了问题标题和正文。
要明确:
EDIT2:
目前,我不确定这个问题是否是失败的微调器焦点。为了调试,我在自定义列表视图中更新textview(// update sensor values
之前)中的传感器值之前添加了30ms的睡眠:
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
我成功地下拉微调器并在textview更新时选择另一个项目(一切都很慢,但有效!)。
新:我现在发现问题可能与adapter.notifyDataSetChanged()
有关,因为当我将文本视图打印出来时,我也无法放下微调器
最重要的是,我真的不知道根本原因是什么,但是当我更新listview中的文本视图频率时,我无法下拉微调器,问题是为什么?
我会很高兴得到任何帮助,谢谢!
答案 0 :(得分:3)
这里的问题是你经常调用adapter.notifyDataSetChanged();在你的onSensorChanged方法中,所以它每次都会绑定listview 每次调用getView,每次都设置微调器值。
我做的是,在onSensorChanged方法中访问了listview的第一个和第二个孩子,并从中访问了texviews并根据需要随时更新它们 你也可以访问你的微调器。
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
// SensorProperties tmp = new SensorProperties();
// tmp.x = sensorEvent.values[0];
// tmp.y = sensorEvent.values[1];
// tmp.z = sensorEvent.values[2];
// if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
// sensorPropertieses.set(0, tmp);
// else
// sensorPropertieses.set(1, tmp);
// adapter.notifyDataSetChanged();
Log.i("tag", "ensorEvent.values[0] = " + sensorEvent.values[0]);
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
View childView = (View) listView.getChildAt(0);
TextView xTextView = (TextView) childView.findViewById(R.id.tvX);
xTextView.setText(String.valueOf(sensorEvent.values[0]));
TextView yTextView = (TextView) childView.findViewById(R.id.tvY);
yTextView.setText(String.valueOf(sensorEvent.values[1]));
TextView zTextView = (TextView) childView.findViewById(R.id.tvZ);
zTextView.setText(String.valueOf(sensorEvent.values[2]));
} else {
View childView = (View) listView.getChildAt(1);
TextView xTextView = (TextView) childView.findViewById(R.id.tvX);
xTextView.setText(String.valueOf(sensorEvent.values[0]));
TextView yTextView = (TextView) childView.findViewById(R.id.tvY);
yTextView.setText(String.valueOf(sensorEvent.values[1]));
TextView zTextView = (TextView) childView.findViewById(R.id.tvZ);
zTextView.setText(String.valueOf(sensorEvent.values[2]));
}
}
答案 1 :(得分:1)
运行此代码,它会给你一些想法!!
public class MainActivity extends ActionBarActivity {
List<myItem> myItemList;
ListView list;
boolean isTouchEvent = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myItemList = new ArrayList<myItem>();
for (int i = 0; i < 9; i++) {
myItem m = new myItem();
m.setMyText("This is item number "+i);
myItemList.add(m);
}
list = (ListView)findViewById(R.id.list);
list.setAdapter(new MyAdapter(this, R.layout.list_item, myItemList));
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(MainActivity.this, "You have clicked item number "+arg2, Toast.LENGTH_SHORT).show();
}
});
list.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
isTouchEvent = true;
return false;
}
});
}
class MyAdapter extends ArrayAdapter<myItem> {
Context ctx;
public MyAdapter(Context context, int resource, List<myItem> objects) {
super(context, resource, objects);
ctx = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder.txt = (TextView)convertView.findViewById(R.id.TextView_txt);
holder.sp = (Spinner)convertView.findViewById(R.id.Spinner_sp);
List<String> spinnerValues = new ArrayList<String>();
for (int i = 0; i < 5; i++) {
String temp = "Val #" + i;
spinnerValues.add(temp);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ctx,android.R.layout.simple_spinner_item,spinnerValues);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.sp.setAdapter(adapter);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.sp.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
isTouchEvent = true;
return false;
}
});
holder.sp.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
if(!isTouchEvent){
return;
}
String spinnerStringValue = (String)holder.sp.getAdapter().getItem(arg2);
holder.txt.setText("You have selected "+ spinnerStringValue );
holder.txt.invalidate();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
holder.txt.setText(myItemList.get(position).getMyText());
return convertView;
}
}
static class ViewHolder {
public TextView txt;
public Button bt;
public Spinner sp;
}
public class myItem {
private String myText="";
public String getMyText() {
return myText;
}
public void setMyText(String myText) {
this.myText = myText;
}
}
}
activity_main.xml中:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
/>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >
<TextView
android:id="@+id/TextView_txt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="16dip" />
<Spinner
android:id="@+id/Spinner_sp"
android:layout_marginLeft="50dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>