问题描述
我知道here中已经问过这个问题,但是我的问题在插入项目的方式上有点不同。我还尝试了this的所有解决方案,但仍然没有运气。
背景:
我有一个RecyclerView
,其项目已分为3列。第一个是TextView
,其余的是EditText
。最初,我为用户提供一个列表,其中只有一个项目,其TextView
设置为1(项目的位置),并且EditText
将填充一些值。一旦用户同时填充了两个EditText
并按下Enter键,我将插入一个新项目,其中TextView
为2(下一个项目的位置)和EditText
。在每次插入新项目时,我都想滚动到RecyclerView
的底部,以便用户可以轻松地编辑EditText
。我不断插入新的项目单位,用户单击Save
按钮,该按钮会将列表中的项目插入数据库表。
问题:
插入第7个项目后,RecyclerView
不会滚动到按钮,因此我使用以下代码对其进行了修复:
linearlayoutmanager.setStackFromEnd(true);
使用上面的代码,我现在可以越过7个项目,但是一旦到达第10个项目,RecyclerView
就不会滚动到底部,因此我必须手动滚动。现在,要插入多少个项目,我将如何继续滚动?
我的代码:
适配器:
public class listadapter extends RecyclerView.Adapter<listadapter.ViewHolder> {
private List<ListModel> original;
public listadapter(List<ListModel> list){ original = list; }
@NonNull
@Override
public listadapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.list_layout,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull listadapter.ViewHolder holder,int position) {
String sNo = original.get(position).getsNo();
String product = original.get(position).getProduct();
String price = original.get(position).getPrice();
holder.sNo.setText(sNo);
holder.product.setText(product);
holder.product.requestFocus();
holder.price.setText(price);
holder.bind();
}
@Override
public int getItemCount() { return original.size(); }
public class ViewHolder extends RecyclerView.ViewHolder {
EditText product,price;
TextView sNo;
public ViewHolder(View itemView){
super(itemView);
sNo = (TextView) itemView.findViewById(R.id.sno);
product = (EditText) itemView.findViewById(R.id.newProduct);
price = (EditText) itemView.findViewById(R.id.newPrice);
}
public void bind() {
addListener(product);
addListener(price);
}
private void addListener(final EditText editText){
editText.setonKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v,int keyCode,KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP &&
keyCode == KeyEvent.KEYCODE_ENTER) {
if (!anyEmptyEditText()){
// insert new empty row
ListModel item = new ListModel(
String.valueOf(getItemCount()+1),"","");
original.add(item);
notifyItemInserted(getItemCount());
} else {
if (editText == product)
price.requestFocus();
else if (editText == price)
product.requestFocus();
}
}else{
// modify adapter by keeping it consistent with
// the data being inserted in `EditText`
ListModel item = new ListModel(String.valueOf(getItemCount()),product.getText().toString(),price.getText().toString());
original.set(getItemCount() - 1,item);
}
return false;
}
});
}
}
private boolean anyEmptyEditText(){
for (int idx = 0; idx < original.size(); idx++)
if (original.get(idx).getProduct().isEmpty() ||
original.get(idx).getPrice().isEmpty())
return true;
return false;
}
}
活动:
public class FormActivity extends AppCompatActivity {
private ArrayList<ListModel> list;
private RecyclerView listView;
private listadapter listadapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_form);
setupAdapter();
}
private void setupAdapter(){
listView = (RecyclerView) findViewById(R.id.newTableContent);
final linearlayoutmanager linearlayoutmanager = new linearlayoutmanager(this);
linearlayoutmanager.setStackFromEnd(true);
listView.setLayoutManager(linearlayoutmanager);
list = new ArrayList<>();
listadapter = new listadapter(list);
listView.setAdapter(listadapter);
}
}
我还想获得代码的优化版本。
解决方法
我通过在插入新项后通过界面与活动对话来解决它:
Adapater:(创建并设置侦听器)
private final NewItem listener;
public interface NewItem {
void onNewItemInsert(boolean inserted);
}
public ListAdapter(List<ListModel> list,NewItem listener){
original = list;
this.listener = listener;
}
在addListener()
中添加项目的地方,我将值设置为侦听器:
if (!anyEmptyEditText()){
// reset of the code
listener.onNewItemInsert(true);
}
活动 :(在setupAdapter()
内部获取侦听器并滚动到新创建的项目)
private void setupAdapter(){
// reset of the code
listAdapter = new ListAdapter(list,new ListAdapter.NewItem() {
@Override
public void onNewItemInsert(boolean inserted) {
if (inserted)
listView.scrollToPosition(listAdapter.getItemCount() - 1);
}
});
// reset of the code
}
事件虽然解决了原始问题,但引入了两个小问题:
在插入新项目时,RecyclerView
似乎会下降一点,然后又回到其原始位置,并且requestFocus()
始终应用于所考虑的最后一个EditText
。我希望在插入新项目时,requestFocus()
始终位于第一个EditText
上。