繁体   English   中英

从第二个活动返回后在第一个活动中更新 Listview

[英]Update Listview in first activity after returning from second activity

我在一个活动中有一个列表视图,在自定义适配器中有一个信息图标。 当用户点击该信息按钮时,下一个活动将打开,当用户点击更新按钮时,在下一个活动中标记出勤后,第二个活动应该完成,第一个活动列表视图应该更新。

我成功地做了什么:我已经成功地标记了出席人数并更改了列表视图的颜色,但我在关闭第二个活动并重新启动第一个活动后这样做了。 通过这种方式,列表视图会因为再次启动活动而更新。

我无法做的事情:我希望当用户点击更新按钮时,只有完成()会调用并且用户返回到上一个更新列表视图的第一个活动。 但是当我这样做时,列表视图不会更新。 我必须返回并再次打开该活动,然后列表视图才会更新,否则不会。 我不想那样。 我还尝试在第一个活动的 onResume 方法中通知适配器,以便当用户从第二个活动返回时,第一个活动列表视图适配器将因 onResume 方法而更新,但它不起作用。 请帮助

我的列表视图活动代码:

public class TeacherWebserviceMainList extends Activity {
int attentedncemarkedCount = 0;
TextView addteacher;
DatabaseHandler databasehandler;
DetailsTeacherwebservice details;
String emis;

ArrayList<DetailsTeacherwebservice> addas = new ArrayList<DetailsTeacherwebservice>();
CustomAdapterTeacherWebservice cusadapter;
ArrayList<DetailsTeacherwebservice> teacherList;
private ListView listcontent = null;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.teacherwebservicemainlist );
    addteacher = (TextView) findViewById(R.id.addteachermenu);

    databasehandler = new DatabaseHandler(TeacherWebserviceMainList.this);
    listcontent = (ListView) findViewById(R.id.teacher_list);
    teacherList = databasehandler.teacherwebserviceList(emis);
    Rsults();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1) {
        if(resultCode == RESULT_OK) {
            String update = data.getStringExtra("update");
            if(update.equals("1"))
            {
                //cusadapter.
                CustomAdapterTeacherWebservice adapter = new CustomAdapterTeacherWebservice(this, addas);

                listcontent.setAdapter(adapter);
            }
        }
    }
}

private void Rsults() {
    addas.clear();
    //DatabaseHandler databaseHandler=new DatabaseHandler(this);
    //ArrayList<ArrayList<Object>> data =  databaseHandler.abcTeacherNew();

    for (int p = 0; p < teacherList.size(); p++) {
        details = new DetailsTeacherwebservice();
        //ArrayList<Object> baris = data.get(p);
        details.setId(teacherList.get(p).getId());
        details.setTeachername(teacherList.get(p).getTeachername());
        details.setTeachercnic(teacherList.get(p).getTeachercnic());
        details.setTeacherno(teacherList.get(p).getTeacherno());
        details.setTeachergender(teacherList.get(p).getTeachergender());
        details.setAttendance(teacherList.get(p).getAttendance());
        details.setTeacherattendancedetails(teacherList.get(p).getTeacherattendancedetails());
        details.setAttendancedatesince(teacherList.get(p).getAttendancedatesince());
        details.setAttendancetrasnferschool(teacherList.get(p).getAttendancetrasnferschool());
        addas.add(details);
    }
    cusadapter = new CustomAdapterTeacherWebservice(TeacherWebserviceMainList.this, addas);
    listcontent.setAdapter(cusadapter);
    listcontent.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {


        }
    });
}

我的列表适配器代码

 public class CustomAdapterTeacherWebservice extends BaseAdapter {

private static ArrayList<DetailsTeacherwebservice> searchArrayList;
DatabaseHandler databaseHandler;
private Context context;
private LayoutInflater mInflater;

public CustomAdapterTeacherWebservice(Context context, ArrayList<DetailsTeacherwebservice> results) {
    searchArrayList = results;
    mInflater = LayoutInflater.from(context);
    databaseHandler = new DatabaseHandler(context);
}

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

@Override
public Object getItem(int p) {
    return searchArrayList.get(p);
}

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

public int getViewTypeCount() {

    return 500;
}



@Override
public int getItemViewType(int position) {

    return position;
}

@Override
public View getView(final int p, View v, ViewGroup parent) {
    ViewHolder holder;
    context = parent.getContext();
    if (v == null) {
        v = mInflater
                .inflate(R.layout.teacherwebserviceadapter, null);
        holder = new ViewHolder();

        holder.name = (TextView) v.findViewById(R.id.teacher_name);
        holder.cnic = (TextView) v.findViewById(R.id.teacher_cnic);
        holder.no = (TextView) v.findViewById(R.id.teacher_phone);
        holder.gender = (TextView) v.findViewById(R.id.gender);
        holder.status = (TextView) v.findViewById(R.id.status);
        holder.info = (ImageView) v.findViewById(R.id.edit);
        holder.l1 = (LinearLayout) v.findViewById(R.id.main);


        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

    holder.name.setText(searchArrayList.get(p).getTeachername());
    holder.cnic.setText(searchArrayList.get(p).getTeachercnic());
    holder.no.setText(searchArrayList.get(p).getTeacherno());
    holder.gender.setText(searchArrayList.get(p).getTeachergender());
    holder.status.setText(searchArrayList.get(p).getAttendance());
    if (searchArrayList.get(p).getAttendance().equals("Absent"))
    {
        holder.l1.setBackgroundColor(Color.parseColor("#DB674D"));
    }
    if (searchArrayList.get(p).getAttendance().equals("Present"))
    {
        holder.l1.setBackgroundColor(Color.parseColor("#7EB674"));
    }
    if (searchArrayList.get(p).getAttendance().equals("Transfer Out"))
    {
        holder.l1.setBackgroundColor(Color.parseColor("#FBE87C"));
    }
    if (searchArrayList.get(p).getAttendance().equals("Resigned"))
    {
        holder.l1.setBackgroundColor(Color.parseColor("#4FC3F7"));
    }
    holder.info.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Intent view_order_intent = new Intent(context, Teacherwebservicemainlistupdate.class);
            view_order_intent.putExtra("ID", searchArrayList.get(p).getId());
            view_order_intent.putExtra("tname", searchArrayList.get(p).getTeachername());
            view_order_intent.putExtra("tgender", searchArrayList.get(p).getTeachergender());
            view_order_intent.putExtra("tcnic", searchArrayList.get(p).getTeachercnic());
            view_order_intent.putExtra("tno", searchArrayList.get(p).getTeacherno());
            view_order_intent.putExtra("tatt", searchArrayList.get(p).getAttendance());
            view_order_intent.putExtra("tattdetails", searchArrayList.get(p).getTeacherattendancedetails());
            view_order_intent.putExtra("tattdatesince", searchArrayList.get(p).getAttendancedatesince());
            view_order_intent.putExtra("tatttrasnferout", searchArrayList.get(p).getAttendancetrasnferschool());
            //context.startActivity(view_order_intent);
            ((Activity)context).startActivityForResult(view_order_intent, 1);
        }
    });
    return v;
}

static class ViewHolder {
    TextView name, cnic, no, gender,status;
    ImageView info;
    LinearLayout l1;

}

在适配器代码中,单击 INFO 按钮后,将启动另一个活动,用户可以在其中更新出勤率。

这是单击按钮时更新活动代码:

  update.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        DetailsTeacherwebservice schoolinfo = new DetailsTeacherwebservice();
                schoolinfo.setTeachername(teachername.getText().toString());
                schoolinfo.setTeacherno(teacherno.getText().toString());
                schoolinfo.setTeachercnic(teachercnic.getText().toString());
                schoolinfo.setTeachergender(teachergender.getText().toString());
                schoolinfo.setAttendance(teachergroupstr);
                schoolinfo.setTeacherattendancedetails(absentgrpstr);
                schoolinfo.setAttendancedatesince(txtDate.getText().toString());
                schoolinfo.setAttendancetrasnferschool(transferOutSchool.getText().toString());
                databasehandler.updateteacherwebservice(schoolinfo, emis, identity);
                Toast.makeText(Teacherwebservicemainlistupdate.this, "Updated Successfully", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent();
                intent.putExtra("update", "1");
                setResult(RESULT_OK, intent);
                finish();

            }
        }
    });

单击更新按钮时,我可以再次启动 listview 活动,但这会更改单击的列表项的索引,即因为活动再次启动。 我想要的是,如果我点击第 10 个项目,那么当下一个活动打开并且用户更新出勤率时,它会返回到相同索引位置的上一个活动,这样用户就不必再次滚动以返回第 10 个项目

为列表项单击添加此代码:

 Intent i = new Intent(context, YourAcitivityName.class);
     i.putExtra("position",p);
    startActivityForResult(i, 1);

在更新按钮中添加此代码:

Intent intent = new Intent();
intent.putExtra("update", "1");
intent.putExtra("position",getIntent().getIntExtra("position",0));
setResult(RESULT_OK, intent);        
finish();

当您从活动返回到实施列表视图的活动时,此方法调用:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1) {
         if(resultCode == RESULT_OK) {
             String update = data.getStringExtra("update");
             if(update.equals("1"))
             {
               // add your code to update list view
                 teacherList = databasehandler.teacherwebserviceList(emis);
                 Rsults();
                  YourAdapterClassName adapter = new YourAdapterClassName(this, arrList);

                  listView.setAdapter(adapter);
               listView.smoothScrollToPosition(getIntent().getIntExtra("position",0));
              }
         }     
    }
} 

下面是两个例子,第一个是 ListView 的源是一个 List(在这种情况下使用自定义适配器),第二个是源是一个 Cursor(使用 SimpleCursorAdapter)

许多人陷入的陷阱只是使用以下内容更新列表:-

    myList = method();
    myAdapter.notifyDataSetChanged();

猜测一下,这就是你掉入的陷阱。

什么时候应该做的是使用 List 的方法来改变它(例如clearaddaddAllremove )。

我相信这解释了推理 - Java 是“按引用传递”还是“按值传递”?

示例 1 - 列出来源:-

/**
 * Build or rebuild the List of TaskData's, instantiate the
 * Custom Array Adapter if needed and also notify the adapter
 * if the List may have been changed.
 */
private void prepTasksCustomArrayList() {
    // Determine if the adpater needs to be notified of changes
    boolean notify_dataset_changed = (mCsr != null && mCustomArrayAdapter != null);

    // If the List is not null then assume that it has changed
    // otherwise just get the List
    if (mTasks != null) {
        mTasks.clear();
        mTasks.addAll(dbhlpr.getAllTasks());
    } else {
        mTasks = dbhlpr.getAllTasks();
    }
    // If the adapter is null then instantiate it
    if (mCustomArrayAdapter == null) {
        mCustomArrayAdapter = new CustomArrayAdapter(
                this,
                R.layout.taskdata_item,
                mTasks);
    }
    // Notify the adapter that the List has changed
    if (notify_dataset_changed) {
        mCustomArrayAdapter.notifyDataSetChanged();
    }
}

笔记

  • 这用于设置和更改/更新适配器附加到的ListView
  • 所需要的只是在代码中的适当位置调用该方法,例如在 onCreate、onResume、onItemClick/LongClick 之后的活动中。
    • 例如在 onCreate 中:-
    • mTaskList = this.findViewById(R.id.tasklist); // The ListView
    • prepTasksCustomArrayList()
    • mTaskList.setAdapter(mCustomArrayAdapter)
    • 并在onresume (结合onCreate的 3 行)
    • prepTasksCustomArrayList()
  • 我不相信这种方式很常见,通常您会在onCreate看到正在设置的适配器。
  • mTasks.addAll(dbhlpr.getAllTasks()); 是什么获取源数据。

示例 2 - 光标作为源

/**
 * Build or rebuild the List via Cursor using the bespoke layout
 */
private void prepCursorListBespoke() {
    boolean swapcursor = (mCsr != null && mCursorAdapter2 != null);
    if (mCursorAdapter2 == null) {
        mCursorAdapter2 = new SimpleCursorAdapter(this,R.layout.taskdata_item,mCsr,
                new String[]{ Datasource.TASKS_ID_COL,
                        Datasource.TASKS_TYPE_COL,
                        Datasource.TASKS_NAME_COL,
                        Datasource.TASKS_OWNER_COL,
                        Datasource.TASKS_EXPIRATION_COL},
                new int[]{R.id.task_id,
                        R.id.task_type,
                        R.id.task_name,
                        R.id.task_owner,
                        R.id.task_expiration},
                0);
    }
    if (swapcursor) {
        mCursorAdapter2.swapCursor(mCsr);
    }
}

笔记

  • prepCursorListBespoke方法的使用方式与示例 1 相同。
  • notifyDataSetChanged可以用来代替的swapCursor
    • 我使用swapCursor因为它更具描述性)。
  • 但是,您只能将swapCursor用于游标。

已添加

以下更改可能会起作用,粗略地说,我已经应用了上面的 List 示例。

RsultsonResume (添加)调用,它将通知适配器数据已更改。

由于代码不足,该代码尚未经过测试 (a DatabaseHandler类没有代码,b) DetailsTeacherwebservice类没有代码)。 因此可能会出现错误。

寻找//++++++++++++++...应该有注释来说明已完成/更改的内容。

public class MainActivity extends Activity {
    int attentedncemarkedCount = 0;
    TextView addteacher;
    DatabaseHandler databasehandler;
    DetailsTeacherwebservice details;
    String emis;

    ArrayList<DetailsTeacherwebservice> addas = new ArrayList<DetailsTeacherwebservice>();
    CustomAdapterTeacherWebservice cusadapter;
    ArrayList<DetailsTeacherwebservice> teacherList;
    private ListView listcontent = null;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.teacherwebservicemainlist);
        addteacher = (TextView) findViewById(R.id.addteachermenu);

        databasehandler = new DatabaseHandler(TeacherWebserviceMainList.this);
        listcontent = (ListView) findViewById(R.id.teacher_list);
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        //MOVED  On ItemClickListener block FROM Rsults to here.
        listcontent.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                                    long id) {


            }
        });
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        teacherList = databasehandler.teacherwebserviceList(emis);
        Rsults();
    }

    
    // Probably don't even need onActivityResult
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1) {
            if (resultCode == RESULT_OK) {
                String update = data.getStringExtra("update");
                if (update.equals("1")) {
                    //cusadapter.
                    //CustomAdapterTeacherWebservice adapter = new CustomAdapterTeacherWebservice(this, addas);
                    //+++++++++++++++++++++++++++++++++++
                    // Commented out
                    //listcontent.setAdapter(adapter);
                }
            }
        }
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // Added onResume to call Rsults
    @Override
    public void onResume() {
        super.onResume();
        Rsults();
    }

    private void Rsults() {
        
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // ADDED 4 lines to see if the notifyDataSetChanged is required
        boolean notifydschg_needed = false;
        if (cusadapter != null) {
            notifydschg_needed = true;
        }
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // YOU NEED TO GET THE TEACHER LIST AGAIN AS THE DB HAS CHANGED
        teacherList = databasehandler.teacherwebserviceList(emis);
        
        addas.clear();
        //DatabaseHandler databaseHandler=new DatabaseHandler(this);
        //ArrayList<ArrayList<Object>> data =  databaseHandler.abcTeacherNew();

        for (int p = 0; p < teacherList.size(); p++) {
            details = new DetailsTeacherwebservice();
            //ArrayList<Object> baris = data.get(p);
            details.setId(teacherList.get(p).getId());
            details.setTeachername(teacherList.get(p).getTeachername());
            details.setTeachercnic(teacherList.get(p).getTeachercnic());
            details.setTeacherno(teacherList.get(p).getTeacherno());
            details.setTeachergender(teacherList.get(p).getTeachergender());
            details.setAttendance(teacherList.get(p).getAttendance());
            details.setTeacherattendancedetails(teacherList.get(p).getTeacherattendancedetails());
            details.setAttendancedatesince(teacherList.get(p).getAttendancedatesince());
            details.setAttendancetrasnferschool(teacherList.get(p).getAttendancetrasnferschool());
            addas.add(details);
        }
        
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        //Just create the adapter and attach it to the listview once
        if (cusadapter == null) {
            cusadapter = new CustomAdapterTeacherWebservice(TeacherWebserviceMainList.this, addas);
            listcontent.setAdapter(cusadapter);
        }
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Notify the adapter that the data has been changed 
        if(notifydschg_needed) {
            cusadapter.notifyDataSetChanged();
        }
    }
}

// 你必须在 onResume 方法中设置适配器中的数据

 @Override
    protected void onResume() {
        super.onResume();
    }

您可以在这种情况下使用 eventbus:
这是一个例子:

在你的 build.gradle 文件中

compile 'org.greenrobot:eventbus:3.0.0'

在活动中有列表视图:

@Override
public void onStart() {
     super.onStart();
     EventBus.getDefault().register(this); // register event
}

@Override
public void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this); // unregister event
}

@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(EventBusInfo eventBusInfo) {
    if (eventBusInfo.getProcessId() == 99) {
        // eventBusInfo.getData();
        notifyDataSetChanged();
    }
}

在更新活动中

yourButtonFinish.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
    finish();
    EventBusInfo event = new EventBusInfo();
    event.setProcessId(99);
    //event.setData(object) //if you want get data back
    EventBus.getDefault().post(event);
    }
});

类 EventBusInfo

public class EventBusInfo {
private int processId;
private Object data;

public EventBusInfo(int processId, Object data) {
    this.processId = processId;
    this.data = data;
}

public EventBusInfo() {
}

public EventBusInfo(int processId) {
    this.processId = processId;
}

public Object getData() {
    return data;
}

public void setData(Object data) {
    this.data = data;
}

public int getProcessId() {
    return processId;
}

public void setProcessId(int processId) {
    this.processId = processId;
}
}

在每次更改时保存列表项,然后使用intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)重新启动适配器的 Activity 以关闭旧的 ListView。 是我所做的,它工作正常。 如果列表不为空,我会使用适配器重新启动活动,并且我有一个新的 ListView 关闭前一个。 或者如果它是空的,我开始一个不同的活动(没有一个空的 ListView) 每次使用 Gson 保存和加载列表项到SharedPreferences出于某种原因, notifyDataSetChanged()在我的情况下不起作用,所以我更喜欢这个解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM