6

現在、ABS、ActionBar タブ、および TabsAdapter/ViewPager を使用して、アプリの適切なタブ レイアウトを作成しています。トップに 5 つ以上のカテゴリ タブがあります。最終的には、ユーザーが新しいカテゴリを追加できるようになります (これは後で設定します)。そのため、現時点では、SherlockFragmentActivity多くのSherlockFragmentカテゴリ ファイルを含むメインがあります。メイン SFA の onCreate で、次のように actionBar を構築し、そのすべてのタブを追加します。

mTabsAdapter.addTab(bar.newTab().setText(R.string.login),
            LoginFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("Geographics"),
            GeoFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText(R.string.economics),
            EconFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText(R.string.elections),
            ElectionsFragment.class, null);

代わりに私がやりたいことはCategoryFragment、特定の選挙、地理、経済などをすべて使用するのではなく、新しい解決策を作成することです。誰も解決策を想像できますか? 理想的には、追加されるタブに文字列を渡すだけで、文字列に基づいて CategoryFragment を膨らませることができます。コードが複数のクラスで非常に冗長であるため、このソリューションが必要です。クラスが実際に実行するのは、SQL dB オンラインからのものをロードして、独自のカテゴリのデータのみを取得することだけです。

ここに私の TabsAdapter クラスがあります:

public class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
    private final Context mContext;
    private Polling activity;
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

    final class TabInfo {
        private final Class<?> clss;
        private final Bundle args;
        //private final String title;
                    //This string is implemented only as part of my attempt!

        TabInfo(Class<?> _class, Bundle _args, String _title) {
            clss = _class;
            args = _args;
            title = _title;
        }
    }
    /*Constructor method that adds a TabsAdapter to each tab that is created.
     * It also adds the ViewPager to each tab so that the user can swipe to change tabs.
     */
    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        this.activity = (Polling) activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    /*This is the method I've been trying to use to solve the problem, but it's not really cutting it!*/

    public void buildTabs() throws ClassNotFoundException { 
        String [] tabs = {"Econ", "Elections", "Geo", "Politics", "Science", "Finance", "Religion", 
                "Military", "International" };
        final String resource = "R.string.";            
        mTabsAdapter.addTab(bar.newTab().setText("Login"),
                LoginFragment.class, null, "Login");
        for (int j = 0; j < tabs.length; j++) {
            String res = resource + tabs[j];
            String clas = tabs[j] + "Fragment";
            String total = "com.davekelley.polling." + clas;
        mTabsAdapter.addTab(bar.newTab().setText(tabs[j]),
                CategoryFragment.class, null, tabs[j]);
        }           
    }

    /*A fairly simple method that sets the TabInfo for each tab so that the TabsAdapter
     * knows which class the tab that is being added actually belonds to. It also updates
     * the UI interface when each tab is added. 
     */

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, String title) {
        TabInfo info = new TabInfo(clss, args, title);
        tab.setTag(info);
        tab.setTabListener(this);
        mTabs.add(info);
        mActionBar.addTab(tab);
        notifyDataSetChanged();
    }   

    public int getCount() {
        return mTabs.size();
    }
    /*A method that is used in other classes to allow each tab Fragment to 
     * access its inherited methods from a mother-class, in this case, SherlockFragment
     */

    public int getPosition(SherlockFragment fragment) {
        for (int j = 1; j < mTabs.size(); j++) {
            TabInfo info = (TabInfo) mActionBar.getTabAt(j).getTag();
            if (info.title.matches(mTabs.get(j).title)) {
                return j;
            }
        }
        return -1;


    }
    public SherlockFragment getItem(int position) {
        TabInfo info = mTabs.get(position);
        return (SherlockFragment)Fragment.instantiate(mContext, info.clss.getName(), info.args);
    }
    /*This method reads the user's selection for a new tab and sets that tab as
     * the new current focus.*/
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
        selectInSpinnerIfPresent(position, true);
    }

    private void selectInSpinnerIfPresent(int position, boolean animate) {
        try {
            View actionBarView = findViewById(R.id.abs__action_bar);
            if (actionBarView == null) {
                int id = getResources().getIdentifier("action_bar", "id", "android");
                actionBarView = findViewById(id);
            }

            Class<?> actionBarViewClass = actionBarView.getClass();
            Field mTabScrollViewField = actionBarViewClass.getDeclaredField("mTabScrollView");
            mTabScrollViewField.setAccessible(true);

            Object mTabScrollView = mTabScrollViewField.get(actionBarView);
            if (mTabScrollView == null) {
                return;
            }

            Field mTabSpinnerField = mTabScrollView.getClass().getDeclaredField("mTabSpinner");
            mTabSpinnerField.setAccessible(true);

            Object mTabSpinner = mTabSpinnerField.get(mTabScrollView);
            if (mTabSpinner == null) {
                return;
            }

            Method setSelectionMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod("setSelection", Integer.TYPE, Boolean.TYPE);
            setSelectionMethod.invoke(mTabSpinner, position, animate);

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public void onPageScrollStateChanged(int state) {}
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
    /* This is the method that actually draws the newest tab onto the screen when
     * it is selected.*/
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        mViewPager.setCurrentItem(tab.getPosition());

        sp = getSharedPreferences("prefs", MODE_PRIVATE);
        SharedPreferences.Editor preferencesEditor = sp.edit();
        preferencesEditor.putInt("lastPosition", mViewPager.getCurrentItem());
        preferencesEditor.commit();
    }
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
    public void onTabReselected(Tab tab, FragmentTransaction ft) {}
    public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {}
    public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {}
}
4

2 に答える 2

1

複数のクラスではなく、1 つの Fragment クラス、たとえばBaseFragmentを使用する必要があります。この新しい Fragment に文字列 (識別子) を渡すことで、これを行います。また、これらすべてのフラグメントでいくつかのコードを実行しているため、新しいアプローチを使用することをお勧めします。

ただし、このBaseFragmentに識別子を渡すと、コードが乱雑になるだけであり、これらすべてを処理する必要がありますif...else。実際にはすべてこの識別子に関連しており、コードを移動する必要があるため、コードは実際には同じです。この BaseFragment への特定のフラグメントの。したがって、このアプローチには付加価値はありません。すべてのフラグメントを保持し、タブを追加するときにこの「識別子」を実際に使用して、追加する適切なフラグメントを選択できます。


多くのフラグメントで実行されるコードについて。これは非常に基本的なアプローチです。

Fragment を拡張するクラス BaseFragment を作成します。(ここでは素朴ですcommon())この一般的なことを行う関数を追加します。最後に、すべての Fragment が Fragment の代わりにこの BaseFragment を拡張するようにします。これで、 を呼び出すことができますcommon()。(繰り返しますが、 , , が必要な場合がありcommon1()ますcommon2())...

于 2012-12-28T11:05:13.880 に答える
1

クラスでは、リフレクションを使用する必要があります。文字列名だけでは不十分です。したがって、おそらく次のように書く必要があります。

String clas = tabs[j] + "Fragment";
String total = "com.davekelley.polling." + clas;
Class<?> theClass = Class.forName (total);

リソースについては、 のようなものを単純に書くことはできません。String res = "R.string" + tabs[j];関数を使用する必要がありますgetIdentifier()例については、 Android の動的リソース読み込みを参照してください。

于 2012-12-28T14:01:34.537 に答える