Android:从由ViewPager2和TabLayout管理的片段向包含的活动发送数据。

huangapple 未分类评论41阅读模式
英文:

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(&quot;POS&quot;);
        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(&quot;users&quot;).document(user.getUid()).collection(&quot;projects&quot;).document(pos);
        reference.get().addOnCompleteListener(task -&gt; {
            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, &quot;Page #&quot; + 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) -&gt; 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(&quot;Add a new snippet&quot;)
                        .setView(view)
                        .setPositiveButton(R.string.ok, (dialog, which) -&gt; {
                            EditText et = view.findViewById(R.id.editText_filename);

                            // Add a new file to the list
                            currentProject.addCodeFile(new CodeFile(et.getText().toString(), &quot;&quot;));

                            // 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&#39;t freeze the UI thread, perform the request asynchronously using Retrofit
                Call&lt;List&lt;Compiler&gt;&gt; called = entryPoint.getService().list();
                called.enqueue(new Callback&lt;List&lt;Compiler&gt;&gt;() {
                    @Override
                    public void onResponse(Call&lt;List&lt;Compiler&gt;&gt; call, Response&lt;List&lt;Compiler&gt;&gt; response) {
                        List&lt;Compiler&gt; compilers = response.body();
                        Toast.makeText(EditorActivity.this, compilers.get(0).displayName, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onFailure(Call&lt;List&lt;Compiler&gt;&gt; call, Throwable t) {
                        Toast.makeText(EditorActivity.this, &quot;Failed to send request: &quot; + 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&lt;CodeFile&gt; dataSet;

    public EditorTabPageAdapter(@NonNull FragmentActivity fragmentActivity, List&lt;CodeFile&gt; 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&lt;CodeFile&gt; 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

huangapple
  • 本文由 发表于 2020年4月5日 02:42:08
  • 转载请务必保留本文链接:https://java.coder-hub.com/61033066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定