java - 有没有办法将表格保存到 Firebase 中?实时还是 Firestore?
问题描述
我制作了这个移动应用程序,可以在按下按钮后添加表格行。每行包含一个 Edittext、四个下拉菜单(微调器)和一个删除行的按钮。在我按下“添加”按钮后,每一行都像是一个副本。现在,我唯一的问题是如何将特定内容保存到 firebase 的实时数据库中,或者可以 firestore。你们有关于如何做到这一点的建议,任何资源,还是这个问题很广泛?我可以指定一些你感到困惑的事情。
我可以保存一个包含文档标题的编辑文本,并且它成功地工作,除了表格行,因为它包含多种数据类型。我刚刚听说 firebase 只能保存原始数据类型。
这是与问题相关的代码,所以我不必粘贴所有 357 行代码。
private android.support.v7.widget.Toolbar maintoolbar, editToolBar;
private FirebaseAuth mAuth;
private FloatingActionButton fab;
private RelativeLayout layoutMain;
private RelativeLayout layoutButtons;
private RelativeLayout layoutContent;
private boolean isOpen = false;
private Button addnewRowButton, saveItButton;
private EditText titleofDoc;
private Context context = null;
private ProgressBar pb;
private DatabaseReference dr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
dr = FirebaseDatabase.getInstance().getReference().child("Notes").child(mAuth.getCurrentUser().getUid());
maintoolbar = findViewById(R.id.mainToolBar);
setSupportActionBar(maintoolbar);
getSupportActionBar().setTitle("Files");
layoutMain = findViewById(R.id.mainLays);
layoutButtons = findViewById(R.id.layoutButtons);
layoutContent = findViewById(R.id.layoutContent);
addnewRowButton = findViewById(R.id.AddRow);
saveItButton = findViewById(R.id.SaveThis);
titleofDoc = findViewById(R.id.TitleofDoc);
editToolBar = findViewById(R.id.main_edit_toolbar);
pb = findViewById(R.id.progressBar2);
saveItButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String title = titleofDoc.getText().toString().trim();
if (!TextUtils.isEmpty(title)) {
pb.setVisibility(View.VISIBLE);
createNew(title);
pb.setVisibility(View.INVISIBLE);
} else {
Snackbar.make(v, "Fill Empty Fields", Snackbar.LENGTH_SHORT).show();
pb.setVisibility(View.INVISIBLE);
}
}
});
addnewRowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addNewRow();
}
});
fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewMenu();
}
});
}
这是制作表格行的方法。
private void addNewRow() {
final TableLayout tl = findViewById(R.id.tbllays);
String[] teamRoles = {"Director", "Marketing", "Team", "All"};
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, teamRoles);
context = getApplicationContext();
//adds new row
final TableRow tbr = new TableRow(context);
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
tbr.setLayoutParams(layoutParams);
//add edittext to name the task
EditText editText = new EditText(context);
editText.setHint("Add Task");
tbr.addView(editText, 0);
//add spinner to assign teams
Spinner toDo = new Spinner(context);
toDo.setAdapter(adapter);
tbr.addView(toDo, 1);
//add spinner to assign teams
Spinner InProgress = new Spinner(context);
InProgress.setAdapter(adapter);
tbr.addView(InProgress, 2);
//add spinner to assign teams
Spinner Test = new Spinner(context);
Test.setAdapter(adapter);
tbr.addView(Test, 3);
//add spinner to assign teams
Spinner Done = new Spinner(context);
Done.setAdapter(adapter);
tbr.addView(Done, 4);
// Add a button in the second column
Button button = new Button(context);
button.setText("X");
tbr.addView(button, 5);
button.setBackgroundColor(Color.rgb(159, 168, 218));
// Get delete table row button.
Button deleteRowButton = (Button) button;
deleteRowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tbr.removeAllViews();
}
});
tl.addView(tbr);
}
这是只能保存标题而不是内容(本例中为表格行)的方法。
private void createNew(String title) {
if (mAuth.getCurrentUser() != null) {
final DatabaseReference newThingRef = dr.push();
final Map thingMap = new HashMap();
thingMap.put("title", title);
thingMap.put("timestamp", ServerValue.TIMESTAMP);
Thread mainThread = new Thread(new Runnable() {
@Override
public void run() {
newThingRef.setValue(thingMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Note added", Toast.LENGTH_SHORT).show();
Intent MainIntent = new Intent(MainActivity.this, MainActivity.class);
startActivity(MainIntent);
} else {
String error = task.getException().getMessage();
Toast.makeText(MainActivity.this, "ERROR: " + error, Toast.LENGTH_LONG).show();
}
}
});
}
});
mainThread.start();
} else {...}
}
这是xml文件(编辑器所在的部分)
<RelativeLayout
android:id="@+id/layoutContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/mainToolBar"
>
<RelativeLayout
android:id="@+id/layoutButtons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:gravity="center"
android:visibility="gone">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainEditor">
<LinearLayout
android:id="@+id/LinLay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="370dp">
<android.support.v7.widget.Toolbar
android:id="@+id/main_edit_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme" />
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true" />
<EditText
android:id="@+id/TitleofDoc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:ellipsize="end"
android:hint="@string/title"
android:importantForAutofill="no"
android:inputType=""
android:maxHeight="1dp"
android:maxLength="30"
android:maxLines="1"
android:padding="10dp"
tools:targetApi="o" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:alpha=".3"
android:background="@android:color/black" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<TableLayout
android:id="@+id/tbllays"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/AddRow"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_weight=".1"
android:background="@color/colorAccent"
android:text="@string/add_row"
android:textColor="@color/colorPrimaryDark" />
<Button
android:id="@+id/SaveThis"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_weight=".1"
android:background="@color/colorPrimaryDark"
android:text="@string/save" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="*">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/task" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:text="@string/to_do" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_weight=".1"
android:text="@string/in_progress" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:layout_weight=".1"
android:text="@string/testing" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="4"
android:layout_weight=".1"
android:text="@string/done" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="5"
android:layout_weight=".1"
android:text="@string/delete" />
</TableRow>
</TableLayout>
</HorizontalScrollView>
</LinearLayout>
</ScrollView>
</RelativeLayout>
</RelativeLayout>
忽略用户部分,即仅当用户登录时。
解决方案
您实际上不想保存行,您想保存基础内容。
与其将屏幕上的行视为内容本身,不如将它们视为只是显示您的基础内容。这些底层内容可以随心所欲地备份、修改,而它在屏幕上的表示可以随时完全重建。
要转换您的代码,我建议执行以下一系列步骤:
- 创建类似于
Task
类的东西,它包含您想要的所有字段(例如name
,team
)。 Task
在您当前的 Activity / Fragment 类中存储 s 列表,例如private List<Task> myTasks
.- 编写一个方法
displayTasks
,从布局中删除所有现有行,然后遍历myTasks
并将它们全部绘制到屏幕上。 - 更改
addNewRow
,使其添加一个新Task
的myTasks
,然后调用displayTasks
. - 您现在有一个任务列表,可以直接将其写入 Cloud Firestore,并在以后检索。
我完全知道这个答案不是您所追求的简单的“只做 x”,而是您真正需要的答案!所有步骤都非常简单,当然可以根据您的用例随意修改它们。
一旦您对“屏幕上的内容不是我的数据,只是它的一种表示”这一概念感到满意,您可能需要研究LiveData和ViewModel。它们更棘手,但有很多好处(在链接中解释)。
推荐阅读
- firebase - 如何在 Firebase 的 Firestore 中查询半径包含另一个点的所有点?
- javascript - 为插件更新 jquery 1 到 3
- php - 带计算的array_diff
- yaml - 如何设置孩子的图表值文件?
- python - socket.connect 永远阻塞。如何在不等待响应的情况下发送带有 LENGHT 的 SYN 数据包?
- sql - Redshift中的存储过程将数据加载到表中
- python - Pyspark:多个数组的交集
- c# - ASP.NET CORE,视图模型在传递回控制器时所有字段都为空
- javascript - Javascript Sensors API 在 iOS 上不起作用
- c - 如何让我的 C 代码读取和存储文件