我想在我的应用中列出收藏夹。 我正在使用arrayadapter。
我有一个字符串和一个评级栏,只有一颗星! 我希望如果你按下星星一次,它会点亮星星(并使它成为最喜欢的) 当你再次按它时,星星不会被填满...(现在它不再是最喜欢的了)
我应该在这里写些什么?如果问题,它甚至可以纠正吗?
public class ChooseFavorites extends Activity implements OnItemClickListener
{
String[] stations;
float[] rating;
boolean[] ifCheacked;
RatingAdapter ratingAdapter;
ArrayAdapter<String> arr;
ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_favorites);
stations = getResources().getStringArray(R.array.stations);
rating = new float[stations.length];
ifCheacked = new boolean[stations.length];
Arrays.fill(ifCheacked, false);
ratingAdapter = new RatingAdapter(this, R.layout.favorite_row, stations);
list = (ListView)findViewById(R.id.stationsList1);
list.setAdapter(ratingAdapter);
list.setOnItemClickListener(this);
}
class RatingAdapter extends ArrayAdapter<String>
{
Context ctx;
LayoutInflater inflater;
TextView stationName;
RatingBar star;
public RatingAdapter(Context context, int textViewResourceId, String[] objects)
{
super(context, textViewResourceId, objects);
ctx = context;
inflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if(row==null)
{ // Object reuse
inflater = getLayoutInflater();
row = inflater.inflate(R.layout.favorite_row, parent, false);
}
stationName = (TextView)row.findViewById(R.id.textFavoriteItemInRow);
stationName.setText(stations[position]);
star= (RatingBar)row.findViewById(R.id.ratingBar1);
if (!ifCheacked[position]) //ifChecked is false
{
star.setRating(rating[position]);
star.setTag(position);
ifCheacked[position] = true;
}
else
{
}
star.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener()
{
public void onRatingChanged(RatingBar ratingBar, float rating2, boolean fromUser)
{
if(!fromUser) return;
int index = (Integer)(ratingBar.getTag());
rating[index] = rating2;
}
});
return row;
}
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
}
答案 0 :(得分:3)
可能您不应该使用RatingBar
,而应使用CheckBox
。我完全按照您的需要在我的某个应用中使用CheckBox
。
基本上您需要做的是以下内容:
在 res \ drawable \ 文件夹中,定义一个新的布局文件,假设您将其命名为 checkboxes.xml 。
在该文件中,您将定义如下内容:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/checkbox_star_down" />
<item android:state_checked="false" android:drawable="@drawable/checkbox_star" />
</selector>
在我的情况下,两个绘图都是两个JPG图像,一个是星星闪耀,一个是关闭。
现在在您的行布局中,定义CheckBox
而不是RatingBar
,如下所示:
<CheckBox
android:id="@+id/soloR"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:onClick="somethingChanged"
android:textSize="12sp"
android:textColor="#FFFFFF"
android:button="@drawable/checkboxes"
android:text="@string/soloR" />
很好,您可能会看到android:button
属性设置为您刚刚定义的checkboxes
。完成后,删除star.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() ...
实施,并将其替换为:
onCheckedChangeListener (CompoundButton.OnCheckedChangeListener listener)
onCheckedChanged
的听众提供了两个参数:CompoundButton buttonView, boolean isChecked
。
基本上,第二个告诉你你的星是否闪亮。您的其余代码似乎通常是合理的,但是:
我不会进行row = convertView
分配。这是我多次见过的一种做法,没有任何意义,直接在convertView
实例上工作。
我不知道你在ListView
内有多少行,但如果它们太多或者它们难以渲染,我会考虑使用viewHolder
秒。如果你还没有与他们合作,那么nice link可以解释这一点。
我看到你在每一行都使用findViewById()
。这可能会导致巨大的性能问题,因为这种调用非常昂贵。我会在你的类中保存两个drawable(假设你的星可能只有2个声明),并在构造函数中分配它们,所以你只处理它们一次 - 或者正如我之前所说,使用viewHolder
s此
请记住一件事:如果您没有保存更改的状态,那么一旦您的行&#34;消失&#34;从屏幕(例如,因为用户在列表中滚动)并且新呈现的行,您将看到先前的状态 - 即,不会保存更改。为此,您在ArrayAdapter
扩展程序中处理数据非常重要,每次用户点击星标时,都会在班级中保存其状态。我的意思是构造函数参数的第三个:public RatingAdapter(Context context, int textViewResourceId, String[] objects)
。现在你只需拨打super
,但你不能保存它。请注意,这是您的工作数据,任何更改都应反映在该Object数组中,否则每次您渲染行时,都不会保存更改。例如:
class RatingAdapter extends ArrayAdapter<String>
{
Context ctx;
LayoutInflater inflater;
TextView stationName;
RatingBar star;
ArrayMap<String, Boolean> rowLayout = ArrayMap<String, Boolean>();
public RatingAdapter(Context context, int textViewResourceId, String[] objects)
{
super(context, textViewResourceId, objects);
ctx = context;
inflater = LayoutInflater.from(context);
for (String rowText : (String) objects)
rowLayout.put(rowText, false); // Supposing all your initial stars will be off
}
现在,您只需同步getView()
方法即可告知Android 应如何进行管理。例如,如果值是false
,那就把它放在一起 - 否则,把闪亮的星星等等放在一起。
----编辑----
关于如何跟踪变化:我不知道你是否最终决定使用viewHolder
,所以我只是说明全局案例。
所有变更并且您希望继续跟踪的内容都应该在getView()
方法中完成。在该方法中,请参阅第二个参数是名为View
的{{1}}。说得非常模糊,这是每一行的布局,即每行的所有内容都包含在每个convertView
中。所以基本上,每行至少会调用convertView
一次。
假设您有一个布局,其中getView()
的ID为CheckBox
,而lvCheckBox
的ID为TextView
。您可以通过调用来有效地获得其中任何一个,例如:
lvTextView
任何监听器也应该在TextView tv = (TextView) convertView.findViewById(R.id.lvTextView);
方法中定义(如前所述)。从您的代码开始,您似乎已经清楚了解到目前为止的事情。
现在,如何管理更改:考虑到您需要实现我之前发布的关于在getView()
扩展中存储数据结构的内容,您应该注意3个概念:
ArrayList
:position
的第一个参数是调用渲染项的位置。但请注意,当您在getView()
方法中定义听众时,您也可以访问此参数,这一点至关重要。
getView()
:getItem(position)
是来自getItem()
类的方法,它从列表中返回一个项目。在ArrayAdapter
上调用此方法将返回正在呈现的项目。它会返回您position
所属的类型,因此,如果您有ArrayAdapter
个,那么您将获得String
。
String
。每次数据集更改时,都必须在适配器上调用此方法。理想的方法是在调用Fragment / Activity中执行此操作,但如果您不能(例如,因为您不知道何时会被触发(侦听器)),您可以在您的内部获得适配器监听器并在监听器中调用此方法,这样:
notifyDataSetChanged()
了解所有这些,只剩下一步了:从ArrayAdapter的数据集副本中删除该项目,您将使用final ListView lv = (ListView) findViewById(R.id.your_listview));
RatingAdapter adapter = (RatingAdapter) lv.getAdapter();
adapter.notifyDataSetChanged();
了解该项目并致电getItem(position)
在您的适配器上 - 如果您需要在其内部或从您的片段/活动中解雇,则从内部开始。
另一种(可能更简单)方法是在您的片段/活动中调用适配器上的notifyDataSetChanged()
或.add
,然后在其上调用.del
。然而,这并非总是可行。
例如,我有一个notifyDataSetChanged()
的自定义布局。这是我宣布它的方式:
ListView
我在private ArrayList<String> elemlist;
elemlist.add("First row");
elemlist.add("Second one");
MultiLayoutArrayAdapter adapter = new MultiLayoutArrayAdapter(MyActivity.this, R.layout.my_custom_layout, elemlist);
:
Activity
这会出现在我的行上。但有时你不想只是添加或删除,而是修改:这是你的情况(elemlist.add("Yet another row");
adapter.notifyDataSetChanged();
听取被点击),所以当上述内容进入时行动。您必须使用CheckBox
修改项目列表并将其从getItem(position)
结构中删除,然后在rowLayout
内调用notifyDataSetChanged()
。
答案 1 :(得分:0)
您可以通过复选框完成此操作。设置两个图像oncheck(setimage(高亮星))并取消选中(setimage(撤消图像))。
CheckBox fav;
boolean isCheck=false;
如果(!isCheck){
fav.setChecked(true);
checked.setBackgroundResource(R.drawable.blue_star);
}else{
fav.setBackgroundResource(R.drawable.grey_star);
fav.setChecked(false);
}