【发布时间】:2014-05-31 18:33:36
【问题描述】:
我有一个 FragmentActivity,它可以包含用户想要的任意数量的 ListFragment。 ListFragments 在HorizontalScrollView 内并排布置(在ActionBar 中选择一个选项时)。每个 ListFragment 项都包含一个 TextView 和一个 Button。单击 Button 会更改 Button 的 ViewParent 的背景颜色 - 一个包含 Button 和 TextView 的 LinearLayout。
现在,单击每个 ListFragment 中的 Button 会更改其相应列表项的背景颜色,但是在滚动列表项中未单击的按钮时,它们的背景颜色也会更改。这种行为是出乎意料的,因为只有被点击的项目才需要通过相应地点击其 Button 来更改其背景颜色。
ListFragment 的数据来自一个自定义的 SimpleAdapter,它覆盖了 getView(int position, View convertView, ViewGroup parent) 方法,在该方法中我将 setOnClickListener 附加到一个 Button,当单击时它会更改其 ViewParent 的背景颜色。
我在这个问题上花了很多时间,但我无法找到解决方案。有助于理解这种行为的根本原因的解释将非常有用。此外,欢迎任何帮助设置单击时仅设置一个项目的背景颜色的指导。
这是我的自定义适配器 MyCustomAdapter 的代码,它扩展了 SimpleAdapter:
package com.example.androidlistfragmenttest;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.SimpleAdapter;
public class MyAdapter extends SimpleAdapter{
Context context;
public MyAdapter(Context context, List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
if(view == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.fragment_layout, null);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Log.v("GOJIRA","ATOMIC BREATH");
// Changes parent view's background color
View parent = (View) v.getParent();
parent.setBackgroundColor(Color.GREEN);
}
});
}
return view;
}
}
还有 ListFragment:
package com.example.androidlistfragmenttest;
import java.util.ArrayList;
import java.util.HashMap;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragment extends ListFragment {
private ArrayList<HashMap<String,String>> arraylist;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_layout, container, false);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
arraylist = dataGenerator();
MyAdapter adapter = new MyAdapter(getActivity().getApplicationContext(), arraylist, R.layout.fragment_layout,new String[]{"KEY"},new int[]{R.id.text_id});
setListAdapter(adapter);
}
/*
* Method to populate an adapter's data list.
*/
public ArrayList<HashMap<String,String>> dataGenerator(){
HashMap<String,String> hashMap1 = new HashMap<String,String>();
hashMap1.put("KEY", "A");
HashMap<String,String> hashMap2 = new HashMap<String,String>();
hashMap2.put("KEY", "B");
HashMap<String,String> hashMap3 = new HashMap<String,String>();
hashMap3.put("KEY", "C");
HashMap<String,String> hashMap4 = new HashMap<String,String>();
hashMap4.put("KEY", "D");
HashMap<String,String> hashMap5 = new HashMap<String,String>();
hashMap5.put("KEY", "E");
ArrayList<HashMap<String,String>> arraylist = new ArrayList<HashMap<String,String>>();
arraylist.add(hashMap1);
arraylist.add(hashMap2);
arraylist.add(hashMap3);
arraylist.add(hashMap4);
arraylist.add(hashMap5);
return arraylist;
}
}
还有ListActivity:
package com.example.androidlistfragmenttest;
import java.util.Stack;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity {
private Stack<String> tagStack;
private Integer last_tag_number;
public MainActivity(){
last_tag_number = new Integer("0");
tagStack = new Stack<String>();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_fragment:
addColumn();
return true;
case R.id.remove_column:
removeColumn();
return true;
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
/*
* This function adds a column pane to the screen
*
*/
public void addColumn(){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_activity, fragment,tagGenerator());
fragmentTransaction.commit();
}
/*This function removes a column pane from the screen
*
*
*/
public void removeColumn(){
if(tagStack.size() != 0){
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tagStack.pop());
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment);
fragmentTransaction.commit();
}
}
/*
* This function generates tags for each fragment that is displayed on the screen
* The tags pose as unique identifiers for each fragment
*/
public String tagGenerator(){
Integer tag_number;
if(last_tag_number.intValue() == 0){
tag_number = last_tag_number;
int temp = last_tag_number.intValue();
temp+=1;
last_tag_number = Integer.valueOf(temp);
}
else{
tag_number = new Integer(last_tag_number.intValue());
int temp = last_tag_number.intValue();
temp+=1;
last_tag_number = Integer.valueOf(temp);
}
String tag = tag_number.toString();
tagStack.push(tag);
return tag;
}
}
最后是布局。对于 ListFragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
android:layout_margin="5dp" >
<ListView android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label"
android:layout_gravity="start"
/>
<TextView
android:id="@+id/text_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="end"
/>
<Button
android:id="@+id/button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/button"
android:layout_margin="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:clickable="true"
/>
</LinearLayout>
对于 FragmentActivity:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/fragment_activity"
android:layout_width="fill_parent"
android:layout_height = "fill_parent"
android:orientation = "horizontal"
android:gravity="center"
>
</LinearLayout>
</HorizontalScrollView>
【问题讨论】:
标签: android android-listview android-listfragment