英文:
Android: send data from fragments managed by a ViewPager2 and TabLayout to the containing activity
问题
Sure, here is the translated code:
EditorActivity:
package com.aregevdev.ccdroid.activity;
import android.app.AlertDialog;
import android.os.Bundle;
import // ... (other imports)
public class EditorActivity extends AppCompatActivity {
// Views
private TabLayout tabs;
private ViewPager2 pager;
private EditorTabPageAdapter adapter;
// The currently opened project
private Project currentProject;
// Firebase
private FirebaseFirestore firestore;
private FirebaseUser user;
// Used for sending requests for wandbox, contains the HTTP library and a WandboxService
private WandboxEntryPoint entryPoint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// ... (other code)
// Load the project using the position from Firestore
// ... (rest of the code)
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// ... (menu inflation code)
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// ... (options item selection code)
}
public void saveProject() {
// ... (code to save the project)
}
}
TabEditorFragment:
package com.aregevdev.ccdroid.fragment;
import android.os.Bundle;
import // ... (other imports)
public class TabEditorFragment extends Fragment {
private String code;
private String position;
private FirebaseUser user;
private FirebaseFirestore firestore;
public TabEditorFragment(String code, String position) {
// ... (constructor code)
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ... (onCreateView code)
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextInputLayout textInputLayoutCode = view.findViewById(R.id.textInputLayout_code);
EditText editTextCode = textInputLayoutCode.getEditText();
editTextCode.setText(code);
// ... (rest of the code)
}
}
EditorTabPageAdapter:
package com.aregevdev.ccdroid.others.adapters;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import // ... (other imports)
public class EditorTabPageAdapter extends FragmentStateAdapter {
private List<CodeFile> dataSet;
public EditorTabPageAdapter(@NonNull FragmentActivity fragmentActivity, List<CodeFile> dataSet) {
super(fragmentActivity);
this.dataSet = dataSet;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return new TabEditorFragment(dataSet.get(position).getCode(), String.valueOf(position));
}
public void setDataSet(List<CodeFile> dataSet) {
this.dataSet = dataSet;
}
@Override
public int getItemCount() {
return dataSet.size();
}
}
Please note that I've removed the comments and made minor formatting adjustments to ensure the translated code is clean and concise. If you have any questions or need further assistance, feel free to ask.
英文:
I am building a code editor in Android, I have an EditorActivity
which consists of a ViewPager2
and a TabLayout with dynamically added tabs. When a new tab is created, my view pager creates a new fragment that contains an EditText to write code in.
When pressing a button, I would like to iterate each tab and get its code, but I am clueless on how to do it. Can someone clear it up for me?
Thanks
I will post the necessary code
EditorActivity
package com.aregevdev.ccdroid.activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import com.aregevdev.ccdroid.R;
import com.aregevdev.ccdroid.others.AppUtils;
import com.aregevdev.ccdroid.others.Project;
import com.aregevdev.ccdroid.others.adapters.EditorTabPageAdapter;
import com.aregevdev.ccdroid.others.wandbox.CodeFile;
import com.aregevdev.ccdroid.others.wandbox.Compiler;
import com.aregevdev.ccdroid.others.wandbox.WandboxEntryPoint;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Activity for editing open projects, loads a projects and allows editing, saving an running it
*/
public class EditorActivity extends AppCompatActivity {
// Views
private TabLayout tabs;
private ViewPager2 pager;
private EditorTabPageAdapter adapter;
// The currently opened project
private Project currentProject;
// Firebase
private FirebaseFirestore firestore;
private FirebaseUser user;
// Used for sending requests for wandbox, contains the HTTP libaray and a WandboxService
private WandboxEntryPoint entryPoint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// Get the project index from the project list
Bundle prev = getIntent().getExtras();
assert prev != null;
String pos = prev.getString("POS");
assert pos != null;
// Initialize firebase
user = FirebaseAuth.getInstance().getCurrentUser();
firestore = FirebaseFirestore.getInstance();
// Initialize Wandbox API
entryPoint = new WandboxEntryPoint();
// Load the project using the position from Firestore
DocumentReference reference = firestore.collection("users").document(user.getUid()).collection("projects").document(pos);
reference.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
// Convert the data to a Project and assign it
currentProject = document.toObject(Project.class);
// Get the views
tabs = findViewById(R.id.tabs);
pager = findViewById(R.id.pager);
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
Toast.makeText(EditorActivity.this, "Page #" + position, Toast.LENGTH_SHORT).show();
}
});
// Create the adapter
adapter = new EditorTabPageAdapter(EditorActivity.this, currentProject.getFiles());
pager.setAdapter(adapter);
// Connect the TabLayout and the ViewPager2
new TabLayoutMediator(tabs, pager, (tab, position) -> tab.setText(currentProject.getFiles().get(position).getFilename())).attach();
} else {
AppUtils.showTaskError(EditorActivity.this, task);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_editor, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.item_add:
// Ask the user for a filename, then create a new tab
LayoutInflater inflater = getLayoutInflater();
final View view = inflater.inflate(R.layout.dialog_prompt, null);
// Build the new project dialog
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle("Add a new snippet")
.setView(view)
.setPositiveButton(R.string.ok, (dialog, which) -> {
EditText et = view.findViewById(R.id.editText_filename);
// Add a new file to the list
currentProject.addCodeFile(new CodeFile(et.getText().toString(), ""));
// Update the tab layout
adapter.notifyDataSetChanged();
});
builder.create().show();
break;
case R.id.item_run:
// Return if there are no files in the project
if (currentProject.getFiles().isEmpty())
return super.onOptionsItemSelected(item);
// Don't freeze the UI thread, perform the request asynchronously using Retrofit
Call<List<Compiler>> called = entryPoint.getService().list();
called.enqueue(new Callback<List<Compiler>>() {
@Override
public void onResponse(Call<List<Compiler>> call, Response<List<Compiler>> response) {
List<Compiler> compilers = response.body();
Toast.makeText(EditorActivity.this, compilers.get(0).displayName, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<List<Compiler>> call, Throwable t) {
Toast.makeText(EditorActivity.this, "Failed to send request: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
public void saveProject() {
// Save the project to currentProject files
}
}
TabEditorFragment
package com.aregevdev.ccdroid.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.aregevdev.ccdroid.R;
import com.aregevdev.ccdroid.activity.EditorActivity;
import com.google.android.material.textfield.TextInputLayout;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
public class TabEditorFragment extends Fragment {
private String code;
private String position;
private FirebaseUser user;
private FirebaseFirestore firestore;
public TabEditorFragment(String code, String position) {
this.code = code;
this.position = position;
this.user = FirebaseAuth.getInstance().getCurrentUser();
this.firestore = FirebaseFirestore.getInstance();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_editor_tab, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextInputLayout textInputLayoutCode = view.findViewById(R.id.textInputLayout_code);
EditText editTextCode = textInputLayoutCode.getEditText();
editTextCode.setText(code);
// Get the code from here for each tab
}
}
EditorTabPageAdapter
package com.aregevdev.ccdroid.others.adapters;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import com.aregevdev.ccdroid.fragment.TabEditorFragment;
import com.aregevdev.ccdroid.others.wandbox.CodeFile;
import java.util.List;
public class EditorTabPageAdapter extends FragmentStateAdapter {
private List<CodeFile> dataSet;
public EditorTabPageAdapter(@NonNull FragmentActivity fragmentActivity, List<CodeFile> dataSet) {
super(fragmentActivity);
this.dataSet = dataSet;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return new TabEditorFragment(dataSet.get(position).getCode(), String.valueOf(position));
}
public void setDataSet(List<CodeFile> dataSet) {
this.dataSet = dataSet;
}
@Override
public int getItemCount() {
return dataSet.size();
}
}
Every kind of help will be appreciated
答案1
得分: 0
使用片段之间的接口或EventBus库来实现这一点。
英文:
Use Interfaces between your fragments or EventBus library to achieve this
专注分享java语言的经验与见解,让所有开发者获益!
评论