gpt4 book ai didi

Android:在onResume中选择ListView Item

转载 作者:行者123 更新时间:2023-11-29 18:07:25 26 4
gpt4 key购买 nike

我有一个使用操作栏的选项卡功能托管多个 fragment 的 Activity 。其中一个 fragment 包含一个 ListView。选择此选项卡后,我想选择某个项目。

为了以编程方式执行此操作,我使用以下代码(其中调用的是 ListView)

private void selectItem(int position)
{
long itemId = calls.GetItemIdAtPosition(position);
calls.PerformItemClick(calls, position, itemId);
}

如果此 ListView 已呈现,并且我正在调用它,则没有问题。但是,如果我从 onResume 调用它,那么代码会执行但最后什么都没有选择。我认为这是因为在我调用 selectItem 时,尚未呈现 ListView 的所有项目。然而,如果我启动一个后台线程,休眠几百毫秒,然后运行相同的代码(当然是在 ui 线程中),一切都很好,但这是一个丑陋的 hack。

现在您可能想知道,“他为什么不使用 calls.setSelection”?问题是,我正在使用执行扩展的自定义布局 - 所以我需要实际单击我想要选择的项目(这反过来会触发所选项目的布局扩展)。但是,我可以直接调用在 PerformItemClick 上执行的代码,结果将是相同的(不执行布局扩展)。

有没有办法让我及时捕捉到“Listview 已完成呈现所有可视项目”的时间点,然后在该时间点执行我的 selectItem 调用?在 ASP.NET 中,我在每个 UI 项目上都有一个事件告诉我它何时完成渲染,所以我在那个时候进行了项目选择,但我没有找到任何东西。

问候斯蒂芬

这是我正在使用的适配器

public class ActiveCallsAdapter: ObservableAdapter<Call>
{

public ActiveCallsAdapter(Activity activity, ObservableCollection<Call> calls)
: base(activity, calls)
{
}

public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
var view = (convertView ?? context.LayoutInflater.Inflate(Resource.Layout.Call, parent, false)) as LinearLayout;
//View view = convertView;
//if (view == null) // no view to re-use, create new
// view = context.LayoutInflater.Inflate(Resource.Layout.Call, null);

SetTextView(view, Resource.Id.CallerName, item.CallerName);
SetTextView(view, Resource.Id.CallerNumber, item.CallerNumber);
SetTextView(view, Resource.Id.CallStatus, item.State.ToString());
SetTextView(view, Resource.Id.CallDuration, item.Duration);

return view;
}

public void Update(LinearLayout view, Call item)
{
SetTextView(view, Resource.Id.CallerName, item.CallerName);
SetTextView(view, Resource.Id.CallerNumber, item.CallerNumber);

string identifier = "callState_" + item.State.ToString();
int resourceId = Application.Context.Resources.GetIdentifier(identifier, "string", Application.Context.PackageName);
string callStateString = item.State.ToString();
if (resourceId != 0)
{
try
{
callStateString = Application.Context.Resources.GetString(resourceId);
}
catch (Exception e)
{
AndroidLogModel.Model.AddLogMessage("ActiveCallsAdapter", "Unable to find call state string with resource id " + resourceId + " state string: " + identifier, 3);
}
}
SetTextView(view, Resource.Id.CallStatus, callStateString);
//SetTextView(view, Resource.Id.CallDuration, item.Duration);
}

public void UpdateDuration(LinearLayout view, Call item)
{
SetTextView(view, Resource.Id.CallDuration, item.Duration);
}

}

以及那个适配器的基类

    public class ObservableAdapter<T>: BaseAdapter<T>
{

protected readonly Activity context;
protected readonly ObservableCollection<T> items;

public ObservableAdapter(Activity context, ObservableCollection<T> collection)
{
this.context = context;
this.items = collection;
//this.collection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(collection_CollectionChanged);
this.items.CollectionChanged += (sender, e) => NotifyDataSetChanged();
}

void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyDataSetChanged();
}

public override T this[int position]
{
get { return items[position]; }
}

public override int Count
{
get { return items.Count; }
}

public override long GetItemId(int position)
{
return position;
}

public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
var view = (convertView ?? context.LayoutInflater.Inflate(Resource.Layout.Call, parent, false)) as LinearLayout;
// configure view here
return view;
}

protected void SetTextView(LinearLayout view, int id, string text)
{
var textView = view.FindViewById<TextView>(id);
if (textView != null)
textView.SetText(text, TextView.BufferType.Normal);
}
}

最佳答案

我的 Mono 技能有限,所以我不知道我是否完全理解你的适配器,无论如何我已经改编了一些旧代码并制作了一个适配器,当点击时展开单个项目,它也会移动 ListView onResume 到想要的位置:

private static class CustomAdapter extends BaseAdapter {

// the data
private ArrayList<String> mData;

// an int pointing to a position that has an expanded layout,
// for simplicity I assume that you expand only one item(otherwise use
// an array or list)
private int mExpandedPosition = -1; // -1 meaning no expanded item
private LayoutInflater mInflater;

public CustomAdapter(Context context, ArrayList<String> items) {
mInflater = LayoutInflater.from(context);
mData = items;
}

public void setExpandedPosition(int position) {
// if the position equals mExpandedPosition then we have a click on
// the same row so simply toggle the row to be gone again
if (position == mExpandedPosition) {
mExpandedPosition = -1;
} else {
// else change position of the row that was expanded
mExpandedPosition = position;
}
// notify the adapter
notifyDataSetChanged();
}

@Override
public int getCount() {
return mData.size();
}

@Override
public String getItem(int position) {
return mData.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.ad_expandedelement,
parent, false);
}
((TextView) convertView.findViewById(R.id.textView1))
.setText(getItem(position));
// see if there is an expanded position and if we are at that
// position
if (mExpandedPosition != -1 && mExpandedPosition == position) {
// if yes simply expand the layout
convertView.findViewById(R.id.button1).setVisibility(
View.VISIBLE);
} else {
// this is required, we must revert any possible changes
// otherwise the recycling mechanism will hurt us
convertView.findViewById(R.id.button1).setVisibility(View.GONE);
}
return convertView;
}

}

onListItemClick 将只是:

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// set the expanded(or collapsed if it's a click on the same row that
// was previously expanded) row in the adapter
((CustomAdapter) getListView().getAdapter())
.setExpandedPosition(position);
}

并且在 onResume 中将有:

@Override
protected void onResume() {
super.onResume();
// set the position to the desired element
((CustomAdapter) getListView().getAdapter()).setExpandedPosition(15);
// set the selection to that element so we can actually see it
// this isn't required but has the advantage that it will move the
// ListView to the desired
// position if not visible
getListView().setSelection(15);
}

R.layout.ad_expandedelement 是一个简单的垂直 LinearLayout,带有一个 TextView 和一个最初隐藏的(可见性设置为消失)按钮。对于此 Button,我更改可见性以模拟在 ListView 中展开/折叠一行。您应该能够理解我的代码,如果您愿意,我可以在 github 上发布完整示例。

关于Android:在onResume中选择ListView Item,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12663096/

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