Android:如何在编辑并重新保存项目后回滚到RecyclerView项目?

时间:2017-01-20 02:57:05

标签: android android-recyclerview android-adapter

我有一个带有CardViews的RecyclerView列表,工作正常。当用户在名为ActActivity的输入UI上输入数据时,会创建CardView。当用户稍后单击CardView以编辑原始数据时,onItemClick方法使用start方法再次启动ActActivity,该方法捕获适配器中正确的CardView项目位置。

当用户单击UI上的“保存”按钮以保存编辑的数据时,ActActivity UI将关闭,RecyclerView列表将自动重新加载(MainActivity),更新的CardView将显示在RecyclerView列表中。我的问题是重新加载时RecyclerView总是滚动到CardView项目列表的顶部。我希望列表返回到被单击以进行编辑的原始CardView。我不知何故需要在适配器中取出原始项目位置,并在重新创建时将其传递回RecyclerView。我需要让RecyclerView知道该位置适用于刚刚编辑的CardView,而不是新的CardView。关于如何完成的任何想法?

MainActivity.java:

public class MainActivity extends AppCompatActivity
    ...
    void loadData(){
    SQLiteDB sqLiteDB = SQLiteDB.getInstance(this);

    List<Contact> contactList = new ArrayList<>();

    Cursor cursor = sqLiteDB.retrieve();
    Contact contact;
    cursor...
    Adapter.addAll(contactList);

    @Override
    public void onItemClick(int position, final View view) {
        cardview = (CardView) view;
        ActActivity.start(this, Adapter.getItem(position));
    }

ActActivity.java:

public class ActActivity extends AppCompatActivity {
    ...
    private Contact contact;

    public static void start(Context context){
        Intent intent = new Intent(context, ActActivity.class);
        context.startActivity(intent);
    }

    public static void start(Context context, Contact contact){
        Intent intent = new Intent(context, ActActivity.class);
        // From the OnItemClick method in the MainActivity the RecyclerView item
        // position from the Adapter is passed into a putExtra bundle that the
        // intent carries to this Activity.  The data is then copied in the onCreate()
        // below using getIntent().getParcelableExtra(). So this is to update an
        // existing CardView item.
        intent.putExtra(ActActivity.class.getSimpleName(), contact);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(layout.activ_act);

        // Fetch data from a parcelable object passed from the MainActivity.
        contact = getIntent().getParcelableExtra(ActActivity.class.getSimpleName());    
        ...
        // Update edited EditText lines to the data Model via contact
        contact.setDataInput(xEditText.getText().toString()); 
        // Update the data in the SQLite database.
        sqLiteDB.update(contact);
        ActActivity.this.finish();

Adapter.java:

public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Contact> contactList;

    public Adapter(Context context) {
        this.context = context;
        this.contactList = new ArrayList<>();
    }

Logcat输出:

RuntimeException:无法恢复活动{com.example.jdw.v53 / com.wimso.v053.MainActivity}:java.lang.NullPointerException                                                                        在android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)                                                                        在android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)                                                                        在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1237)                                                                        在android.os.Handler.dispatchMessage(Handler.java:99)                                                                        在android.os.Looper.loop(Looper.java:137)                                                                        在android.app.ActivityThread.main(ActivityThread.java:4745)                                                                        at java.lang.reflect.Method.invokeNative(Native Method)                                                                        在java.lang.reflect.Method.invoke(Method.java:511)                                                                        在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786)                                                                        在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)                                                                        at dalvik.system.NativeStart.main(Native Method)                                                                     引起:java.lang.NullPointerException                                                                        在com.wimso.v053.MainActivity.onResume(MainActivity.java:370)                                                                        在android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)                                                                        在android.app.Activity.performResume(Activity.java:5082)                                                                        在android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)                                                                        在android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)                                                                        在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1237)                                                                        在android.os.Handler.dispatchMessage(Handler.java:99)                                                                        在android.os.Looper.loop(Looper.java:137)                                                                        在android.app.ActivityThread.main(ActivityThread.java:4745)                                                                        at java.lang.reflect.Method.invokeNative(Native Method)                                                                        在java.lang.reflect.Method.invoke(Method.java:511)                                                                        在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786)                                                                        在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)                                                                        在dalvik.system.NativeStart.main(本地方法)

3 个答案:

答案 0 :(得分:1)

执行以下步骤 -  1.跟踪用户单击要编辑的卡的适配器位置( clickPosition )。这可以通过MainActivity中的状态变量保存。

  1. 当恢复MainActivity时,检查它是否在卡片编辑后启动,如果是,请调用api - recyclerView.scrollToPosition(*clickPosition*)
  2. 当然,这将适用于以下条件 - 1.在ActActivity中,回收器视图数据集未同时修改。 2.如果是新卡或删除卡动作,可能需要以稍微不同的方式进行处理

答案 1 :(得分:1)

您可以使用ActActivity启动context.startActivityForResult(intent,REQUEST_CODE);课程,如下所示

 public static void start(Context context, Contact contact,int position){
        Intent intent = new Intent(context, ActActivity.class);
        // From the OnItemClick method in the MainActivity the RecyclerView item
        // position from the Adapter is passed into a putExtra bundle that the
        // intent carries to this Activity.  The data is then copied in the onCreate()
        // below using getIntent().getParcelableExtra(). So this is to update an
        // existing CardView item.
        intent.putExtra(ActActivity.class.getSimpleName(), contact);
        intent.putExtra("position", position);
        context.startActivityForResult(intent,2);
    }

ActActivity完成保存数据后,您可以使用setResult(intent)

将结果中的适配器位置设置回主Activity

一旦你在MainActivity中获得了onActivityResult()中的结果,你就会知道你在编辑后回来了,所以你可以使用这种方法滚动到这个位置,如下所示

    // Call Back method  to get the Message form other Activity  
@Override  
protected void onActivityResult(int requestCode, int resultCode, Intent data)  
{  
    super.onActivityResult(requestCode, resultCode, data);  
    // check if the request code is same as what is passed  here it is 2  
    if(requestCode==2)  
    {  
        int position=data.getIntExtra("position", 0);  
        //do all your adapter resetting here for recyclerView
        linearLayoutManager.scrollToPositionWithOffset(position, 0);
    }  
}  

答案 2 :(得分:0)

为了做到这一点,第一步是用户点击一张卡片,将其位置保存在首选存储选项中,然后在重新加载C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.Entity.EF6.dll C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Web.dll 时,您可以平滑滚动到特定位置。为此,您需要创建自定义RecyclerView。你就是这样做的:

LinearLayoutManager

然后将其分配给 public class LinearLayoutManagerWithSmoothScroller extends LinearLayoutManager { public LinearLayoutManagerWithSmoothScroller(Context context) { super(context, VERTICAL, false); } public LinearLayoutManagerWithSmoothScroller(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()); smoothScroller.setTargetPosition(position); startSmoothScroll(smoothScroller); } private class TopSnappedSmoothScroller extends LinearSmoothScroller { public TopSnappedSmoothScroller(Context context) { super(context); } @Override public PointF computeScrollVectorForPosition(int targetPosition) { return LinearLayoutManagerWithSmoothScroller.this .computeScrollVectorForPosition(targetPosition); } @Override protected int getVerticalSnapPreference() { return SNAP_TO_START; } } } 并调用RecyclerView

smoothScrollToPosition()