簡體   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