在 android ListView 中,如何迭代/操作所有子视图,而不仅仅是可见的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2114380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In an android ListView, how can I iterate/manipulate all the child views, not just the visible ones?
提问by Corey Trager
The code below does NOT change the text of all of a ListView's
rows because getChildCount()
does not get all of a ListView's
rows, but just the rows that are visible.
下面的代码不会更改所有ListView's
行的文本,因为getChildCount()
不会获取所有ListView's
行,而只会获取可见的行。
for (int i = 0; i < listView.getChildCount(); i++)
{
View v = listView.getChildAt(i);
TextView tx = (TextView) v.findViewById(R.id.mytext);
tx.setTextSize(newTextSize);
}
So, what SHOULD I do?
所以我该怎么做?
Is there code for getting a notification when a ListView's
row becomes visible, so I can set its text size then?
是否有代码可以在ListView's
一行变为可见时收到通知,以便我可以设置其文本大小?
采纳答案by RickNotFred
List13from the API Demos does something similar using OnScrollStateChanged. There may be a better way, though:
API Demos 中的List13使用 OnScrollStateChanged 做了类似的事情。不过,可能有更好的方法:
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:
mBusy = false;
int first = view.getFirstVisiblePosition();
int count = view.getChildCount();
for (int i=0; i<count; i++) {
TextView t = (TextView)view.getChildAt(i);
if (t.getTag() != null) {
t.setText(mStrings[first + i]);
t.setTag(null);
}
}
mStatus.setText("Idle");
break;
. . .
. . .
EDIT BY Corey Trager:
科里·特拉格编辑:
The above definitely pointed me in the right direction. I found handling OnScrollListener.onScroll worked better than onScrollStateChanged. Even if I removed the case statement in onScrollSgtaetChanged and handled every state change, some text wasn't getting resized. But with onScroll, things seem to work.
以上绝对为我指明了正确的方向。我发现处理 OnScrollListener.onScroll 比 onScrollStateChanged 效果更好。即使我删除了 onScrollSgtaetChanged 中的 case 语句并处理了每个状态更改,一些文本也没有调整大小。但是使用 onScroll,事情似乎奏效了。
So, my seemingly working code looks like this:
所以,我看似工作的代码是这样的:
public void onScroll(AbsListView v, int firstVisibleItem, int visibleCount, int totalItemCount)
{
ListView lv = this.getListView();
int childCount = lv.getChildCount();
for (int i = 0; i < childCount; i++)
{
View v = lv.getChildAt(i);
TextView tx = (TextView) v.findViewById(R.id.mytext);
tx.setTextSize(textSize);
}
}
回答by Romain Guy
In a ListView the only children are the visible ones. If you want to do something with "all the children," do it in the adapter. That's the best place.
在 ListView 中,唯一的孩子是可见的。如果你想对“所有的孩子”做一些事情,在适配器中做。那是最好的地方。
回答by Catluc
Not so sure about the performace effect but u can try this.
不太确定性能效果,但你可以试试这个。
//declare the list
ListView list = (ListView)findViewById(R.id.yourListID);
// in my case i have spinners and made a test just to know if this works
Spinner spnWhatever;
View view;
int i =0;
do{
view =list.getAdapter().getView(i,null,null);
//get the spinners from each row
spnWhatever =(Spinner)view.findViewById(R.id.spnTarifas);
i++;
}while(list.getAdapter().getCount() !=i);
回答by Eric Chomba
//Create layout file containing views you want to read input from
//layout/gen_edt_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parLay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtGName"
android:layout_width = "match_parent"
android:layout_height ="wrap_content"
android:hint="Name"
android:inputType="text" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtGIdPass"
style="@style/edt"
android:hint="Id number"
android:inputType="number" />
</LinearLayout>
//Create Empty Activity -> MultipleInput
//layout/activity_multiple_input.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".OpenAccount">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ListView
android:id="@+id/inputLView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="60dp" />
</LinearLayout>
<Button
android:layout_width="wrap_content
android:layout_height="wrap_content"
android:text="Read"
android:onClick="readInput"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent>
</androidx.constraintlayout.widget.ConstraintLayout>
public class MultipleInput extends AppCompatActivity {
//Declare and intialize arrays to store input fields as public modifiers
ArrayList<TextInputEditText> edtNameArr = new ArrayList<>();
ArrayList<TextInputEditText> edtIdsArr = new ArrayList<>();
//Intialize arrays to store input values as public modifiers
ArrayList<String> arr0 = new ArrayList<>();
ArrayList<String> arr1 = new ArrayList<>();
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
listView = findViewById(R.id.listView);
edtNameArr.clear();
edtIdsArr.clear();
arr0.clear();
arr1.clear();
//set number of group fields to be generated
int members = 4;
//initialize class passing fields number and context
edtAdapter = new EdtAdapter(members, getApplicationContext());
//Set retured fields in listView
listView.setAdapter(edtAdapter);
}
public class EdtAdapter extends BaseAdapter {
class ViewHolder {
TextInputEditText edtGName, edtGIdPass;
}
public Context context;
ArrayList<EdtClass> edtArrayList;
int members;
EdtAdapter(int members, Context context) {
this.members = members;
this.context = context;
}
@Override
public int getCount() {
return members;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View contentView, ViewGroup parent) {
View rowView = contentView;
if (rowView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = getLayoutInflater();
rowView = inflater.inflate(R.layout.gen_edt_layout, parent, false);
viewHolder.edtGName = rowView.findViewById(R.id.edtGName);
viewHolder.edtGIdPass = rowView.findViewById(R.id.edtGIdPass);
viewPosition = position;
//loop adding input fields in arrays
for (int i = 0; i < members; i++) {
edtNameArr.add(viewHolder.edtGName);
edtIdsArr.add(viewHolder.edtGIdPass);
}
} else {
viewHolder = (ViewHolder) contentView.getTag();
}
return rowView;
}
}
//Read input when button clicked
public void readInput(View view){
for(int edt = 0; edt<edtNameArr.size(); edt++){
String name = Objects.requireNonNull(edtNameArr.get(edt).getText()).toString();
if(!arr0.contains(name)) {
arr0.add(name);
}
String ids = Objects.requireNonNull(edtIdsArr.get(edt).getText()).toString();
if(!arr1.contains(ids)) {
arr1.add(ids);
}
}
StringBuilder name = new StringBuilder();
StringBuilder idno = new StringBuilder();
//loop through arrays with input, reading and appending values in StringBuilder
for (int m = 0; m < arr0.size(); m++) {
name.append(arr0.get(m)).append(",");
idno.append(arr1.get(m)).append(",");
}
//Show input values in logcat/Toast
Log.e("Names ", name.toString());
Log.e("Ids ", idno.toString());
Toast.makeText(MultipleInput.this, "Names "+ name.toString(), Toast.LENGTH_LONG).show();
}