gpt4 book ai didi

java - android中的“Collection 夹列表”-重新更改评分栏

转载 作者:行者123 更新时间:2023-12-01 23:12:58 25 4
gpt4 key购买 nike

我想在我的应用程序中列出收藏夹。
我正在使用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

}
}

最佳答案

可能您不应该使用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()。这可能会导致巨大的性能问题,因为此调用非常昂贵。我会在类中保存两个可绘制对象(假设您的星星可能只有2个),并在构造函数中分配它们,因此您只需处理一次即可-或正如我之前所说,为此使用 viewHolder
请记住一件事:如果您不保存更改的状态,则一旦您的行从屏幕上“消失”(例如,因为用户在列表中滚动),并且该行是新呈现的,您将看到以前的状态-即,更改将不会保存。为此,在用户每次点击星标时,在 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()方法中完成。在该方法中,看到第二个参数是称为 ViewconvertView。说得很模糊,这就是每一行的布局,即每一行的所有内容都包含在每个 convertView中。因此,基本上,每行至少要调用一次 getView()

假设您有一个布局,其中有一个ID为 CheckBoxlvCheckBox和一个ID为 TextViewlvTextView。您可以通过调用来有效地获取其中任何一个,例如:

TextView tv = (TextView) convertView.findViewById(R.id.lvTextView);


也应该在您的 getView()方法中定义任何侦听器(已经这样做)。从您的代码看来,到目前为止您已经很清楚了。

现在,如何管理更改:考虑到您需要实现我之前发布的关于在 ArrayList扩展名中存储数据结构的内容,您应该意识到以下3个概念:


positiongetView()的第一个参数是被渲染的项目的位置。但也请注意,在 getView()方法中定义侦听器时,您也可以访问此参数,这一点至关重要。
getItem(position)getItem()ArrayAdapter类中的方法,该方法从列表中返回一个项目。在 position上调用此函数将返回正在渲染的项目。它返回 ArrayAdapter的类型,因此,如果有 String,则将得到 String
notifyDataSetChanged()。每次数据集更改时,都必须在适配器上调用此方法。理想的方法是在调用Fragment / Activity中执行此操作,但是如果不能(例如,因为您不知道何时触发它(侦听器)),则可以在侦听器中获取适配器并调用此适配器侦听器中的方法,这种方式:

final ListView lv = (ListView) findViewById(R.id.your_listview));
RatingAdapter adapter = (RatingAdapter) lv.getAdapter();
adapter.notifyDataSetChanged();



知道所有这些之后,只剩下一个步骤:从ArrayAdapter的数据集副本中删除该项目,您将使用 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()内部调用 onCheckedChangeListener()

关于java - android中的“Collection 夹列表”-重新更改评分栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21601465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com