android - রিসাইক্লারভিউতে সম্পাদনা পাঠ্য সামগ্রী সংরক্ষণ করা




android-edittext android-recyclerview (8)

আমার এতে সম্পাদনা EditText সাথে তালিকার আইটেম রয়েছে, আমি জানি না সেখানে কতগুলি আইটেম থাকবে। আমি এডিট টেক্সটে কিছু পাঠ্য প্রবেশ করানোর পরে একটি সমস্যা করেছি এবং তারপরে পুনরায় স্ক্রোল করার পরে আমার প্রথম সম্পাদনা পাঠের কোনও পাঠ্য নেই is

আমি কী ভাবছি এবং কোথায় কোড লিখব যাতে ব্যবহারকারী টাইপ করার সময় বা টাইপিং শেষ করার সময় (আমি একটি টেক্সট TextWatcher সাহায্যে এটি করার চিন্তা TextWatcher ) সম্পাদনা পাঠ্য পাঠ্যটি একটি ফাইলে সংরক্ষণ করা হবে (আমি এটি এতে সংরক্ষণ করব) বাহ্যিক স্টোরেজে একটি টেক্সট ফাইল)

আমার কি ক্রিয়াকলাপের onCreate পদ্ধতিতে বা অ্যাডাপ্টার শ্রেণিতে বা অন্য কোথাও এমন করার কথা রয়েছে?

এখানে কিছু কোড

প্রধান ক্রিয়াকলাপ কোড

 public class MainActivity extends Activity {

    RecyclerView mRecyclerView;
    MyAdapter mAdapter;
    String[] mDataSet= new String[20];
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // generating text for editText Views
        for (int i = 0; i<=19; i++){
        mDataSet[i]= "EditText n: "+i;

    }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mAdapter = new MyAdapter(mDataSet);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setHasFixedSize(true);
    }

আমার অ্যাডাপ্টার কোড

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

private String[] mDataset;


public static class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public EditText mEditText;

    public ViewHolder(View v) {
        super(v);

        mEditText = (EditText) v.findViewById(R.id.list_item_edittext);
    }
}

public MyAdapter(String[] myDataset) {
    mDataset = myDataset;
}

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                 int viewType) {

    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_item, parent, false);

    ViewHolder vh = new ViewHolder(v);
    return vh;
}

@Override
public void onBindViewHolder(ViewHolder holder,  final int position) {
    holder.mEditText.setText(mDataset[position]);

    //without this addtextChangedListener my code works fine ovbiusly
    // not saving the content of the edit Text when scrolled
    // If i add this code then when i scroll all textView that go of screen
    // and than come back in have messed up content
    holder.mEditText.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start,
                                  int before, int count) {
           //setting data to array, when changed
           // this is a semplified example in the actual app i save the text
           // in  a .txt in the external storage
           mDataset[position] = s.toString();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

}

@Override
public int getItemCount() {
    return mDataset.length;
}

এই "addtextChangedListener" ব্যতীত আমার কোড স্ক্রল করার সময় সম্পাদনা পাঠ্যের বিষয়বস্তু সংরক্ষণ না করে অবিচ্ছিন্নভাবে কাজ করে। যদি আমি এই কোডটি যুক্ত করি, যখন আমি সমস্ত সম্পাদনা পাঠ্য ভিউ স্ক্রোল করি যা স্ক্রিন বন্ধ হয় এবং ফিরে আসার চেয়ে সামগ্রী গণ্ডগোল করে।


আপনার অ্যাডাপ্টার ডেটার আকারের সাথে একটি স্ট্রিং অ্যারে তৈরি করুন।

উদাহরণস্বরূপ: String[] texts = new String[dataSize];

আপনার অ্যাডাপ্টারের অভ্যন্তরে অনবিন্দভিউহোল্ডার পদ্ধতিতে, পাঠ্যদর্শনটিতে একটি টেক্সট চ্যাঞ্জডলিস্টনার যুক্ত করুন।

যেমন: -

@Override
    public void onBindViewHolder(Viewholder holder, int position) {

//binding data from array 
   holder.yourEditText.setText(texts [position]);
   holder.yourEditText.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start,
                    int before, int count) {
                //setting data to array, when changed
                texts [position] = s.toString();
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start,
                    int count, int after) {
                //blank
            }

            @Override
            public void afterTextChanged(Editable s) {
                //blank
            }
        });


}

আপনার সমাধানের প্রধান সমস্যাটি হ'ল অনবিন্দ ভিহোল্ডারটিতে পাঠ্য ওয়াচচার বরাদ্দ করা এবং বরাদ্দ করা যা একটি ব্যয়বহুল অপারেশন যা দ্রুত স্ক্রোলগুলির সময় লগগুলি প্রবর্তন করবে এবং এমএডাপ্টারে আপডেট করার জন্য কোন অবস্থানটি নির্ধারণে এটি হস্তক্ষেপ করবে বলে মনে হয়।

অনক্রিটভিউহোল্ডারটিতে সমস্ত ক্রিয়াকলাপ করা আরও বেশি পছন্দনীয় বিকল্প। এখানে সম্পূর্ণ পরীক্ষিত কার্যক্ষম সমাধান:

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

    private String[] mDataset;

    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_edittext, parent, false);
        // pass MyCustomEditTextListener to viewholder in onCreateViewHolder
        // so that we don't have to do this expensive allocation in onBindViewHolder
        ViewHolder vh = new ViewHolder(v, new MyCustomEditTextListener());

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // update MyCustomEditTextListener every time we bind a new item
        // so that it knows what item in mDataset to update
        holder.myCustomEditTextListener.updatePosition(holder.getAdapterPosition());
        holder.mEditText.setText(mDataset[holder.getAdapterPosition()]);
    }

    @Override
    public int getItemCount() {
        return mDataset.length;
    }


    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public EditText mEditText;
        public MyCustomEditTextListener myCustomEditTextListener;

        public ViewHolder(View v, MyCustomEditTextListener myCustomEditTextListener) {
            super(v);

            this.mEditText = (EditText) v.findViewById(R.id.editText);
            this.myCustomEditTextListener = myCustomEditTextListener;
            this.mEditText.addTextChangedListener(myCustomEditTextListener);
        }
    }

    // we make TextWatcher to be aware of the position it currently works with
    // this way, once a new item is attached in onBindViewHolder, it will
    // update current position MyCustomEditTextListener, reference to which is kept by ViewHolder
    private class MyCustomEditTextListener implements TextWatcher {
        private int position;

        public void updatePosition(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            // no op
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            mDataset[position] = charSequence.toString();
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // no op
        }
    }
}

আমার জন্য উপরের সমাধানগুলি কার্যকর হয়নি। তাদের মধ্যে কারও জন্য, শ্রোতা কল করছিল না এবং যখন শ্রোতাকে অনবাইন্ডহোল্ডার পদ্ধতিতে কল করা হয়েছিল তখন শ্রোতাদের ইভেন্টগুলি স্ক্রোল করার সময়ও মনে হয়। 'পাঠ্য' পরিবর্তন হচ্ছে, তাই আমি মূল শ্রোতার চেষ্টা করেছি এবং এটি ভাল কাজ করেছে। আমার অনুমান অনুসারে স্ক্রল করার সময় কোনও কী চাপানো হয় না।

@Override
public int getItemViewType(final int position) {
    return position;
}

কোডটি আমার পক্ষে কাজ করেছিল।


আমি @ ডকারমজির সমাধানটি কার্যকর করেছি, তবে এটি আমার কোনও কাজে আসেনি। সুতরাং, আমি আরও এসেছি এবং সত্যই কাজ সমাধান আছে।

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

    private String[] mDataset;

    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_edittext, parent, false);
        // pass MyCustomEditTextListener to viewholder in onCreateViewHolder
        // so that we don't have to do this expensive allocation in onBindViewHolder
        ViewHolder vh = new ViewHolder(v, new MyCustomEditTextListener());

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // update MyCustomEditTextListener every time we bind a new item
        // so that it knows what item in mDataset to update
        holder.myCustomEditTextListener.updatePosition(holder.getAdapterPosition());
        holder.mEditText.setText(mDataset[holder.getAdapterPosition()]);
    }

    @Override
    public int getItemCount() {
        return mDataset.length;
    }

    @Override
    public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
        ((ViewHolder) holder).enableTextWatcher();
    }

    @Override
    public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
        ((ViewHolder) holder).disableTextWatcher();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public EditText mEditText;
        public MyCustomEditTextListener myCustomEditTextListener;

        public ViewHolder(View v, MyCustomEditTextListener myCustomEditTextListener) {
            super(v);

            this.mEditText = (EditText) v.findViewById(R.id.editText);
            this.myCustomEditTextListener = myCustomEditTextListener;
        }

        void enableTextWatcher() {
            mEditText.addTextChangedListener(myCustomEditTextListener);
        }

        void disableTextWatcher() {
            mEditText.removeTextChangedListener(myCustomEditTextListener);
        }
    }

    // we make TextWatcher to be aware of the position it currently works with
    // this way, once a new item is attached in onBindViewHolder, it will
    // update current position MyCustomEditTextListener, reference to which is kept by ViewHolder
    private class MyCustomEditTextListener implements TextWatcher {
        private int position;

        public void updatePosition(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            // no op
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            mDataset[position] = charSequence.toString();
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // no op
        }
    }
}

মূল সমস্যাটি হ'ল প্রয়োগকৃত পাঠ্য ওয়াচচার আইটেম পুনর্ব্যবহারের সময় কাজ চালিয়ে যায়।

আমি পুনর্ব্যবহারের আগে এটি নিষ্ক্রিয় করার চেষ্টা করেছি, তবে কোনও "ফায়ারক্রাইসেল" ইভেন্টের পদ্ধতি নেই। সুতরাং আমি onViewDetachedFromWindow পদ্ধতিটি ব্যবহার onViewDetachedFromWindow এবং এটি ভালভাবে কাজ করেছে।

এডিট টেক্সট কাস্টম এডিটেবল যুক্ত করার পরে একটি মাত্র সমস্যা আছে F তালিকাটি আবার ব্রেক kes কেন জানি না, সম্ভবত আমি এই সমস্যার সমাধানও খুঁজে পাব


আমি রিসাইক্লারভিউ অবজেক্টের সাথে তেমন পরিচিত নই, তবে তালিকাভিউতে আমার একই সমস্যা ছিল। এইগুলির জন্য, আমি সাধারণত আমার দর্শনগুলিতে সন্নিবেশিত মানগুলিকে উপস্থাপন করে এমন একটি অ্যাডহক ক্লাস তৈরি করি (এটি এডিটেক্সটস, চেকবক্স, রেডিওবটনস ... এর সাথে কাজ করে) এবং সেগুলির মাধ্যমে আপডেট ডেটা পাই। আমি তখন একটি কাস্টম অ্যারেএডাপ্টার তৈরি কন্টেনার অবজেক্টগুলি সমন্বিত করে, প্রতিটি গেটভিউ () থেকে কলব্যাক এডিটেক্সটগুলিতে রাখার জন্য মানগুলি পুনরুদ্ধার করে এবং এই বিষয়গুলিকে টু ডেট রাখার জন্য একটি টেক্সটওয়্যাচার বাস্তবায়ন করি। আবার, আমি ঠিক জানি না যে রিসাইক্লারভিউগুলি কীভাবে কাজ করে তবে এগুলি অ্যাডাপ্টারের সাথে জড়িত থাকলে এটি চেষ্টা করার জন্য এটি আপনার পক্ষে ভাল হ্যাক হতে পারে।


রিসাইক্লারভিউ অ্যাডাপ্টারের মধ্যে অনভিউ রাইসাইক্ল্ড পদ্ধতিটি ওভাররাইড করুন:

public class UploadPhotoAdapter extends RecyclerView.Adapter<UploadPhotoAdapter.MyViewHolder> {
        ArrayList<Feed> feeds;
        Activity activity;
        public UploadPhotoAdapter(Activity activity, ArrayList<Feed> feeds) {
            this.feeds = feeds;
            this.activity = activity;
        }

        @Override
        public UploadPhotoAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.upload_feeds_recycler, parent, false);
            return new UploadPhotoAdapter.MyViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(final UploadPhotoAdapter.MyViewHolder holder, int position) {
            Feed feed = feeds.get(holder.getAdapterPosition());
            holder.captionEditText.setText(feed.getDescription());
            holder.captionEditText.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    feeds.get(holder.getAdapterPosition()).setDescription(s.toString());
                }
                @Override
                public void afterTextChanged(Editable s) {}
            });
        }
        @Override
        public int getItemCount() {
            return feeds.size();
        }

        public class MyViewHolder extends RecyclerView.ViewHolder {
            EditText captionEditText;
            public MyViewHolder(View view) {
                super(view);
                captionEditText = (EditText) view.findViewById(R.id.captionEditText);
            }
        }

    }

হাই @ মিকউই নিশ্চিত করুন যে আপনি পাঠ্য পরিবর্তিত শ্রোতাকে অনবিন্দ ভিহোল্ডার () এ যুক্ত করার পরিবর্তে নীচের পদ্ধতিতে যুক্ত করছেন।

public ViewHolder(View v) {
        super(v);

  yourEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start,
                int before, int count) {
            //setting data to array, when changed
            texts [position] = s.toString();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start,
                int count, int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });


}

আমার মতে এটি @ ডকরমাজির উত্তরের আরও অনুকূলিতকরণ

@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
    mDataSet[holder.getAdapterPosition()] = holder.mEditText.getText().toString();
}




android-recyclerview