使用ListView扩展相同布局的两个片段不是唯一的

时间:2013-08-23 07:35:10

标签: android sqlite listview fragment baseadapter

我正在创建一个小型的Financecontrol-App。现在我遇到一个问题,我不认为我可以在不打电话的情况下处理= D

我使用从Android模板创建的ViewPager获得了一个Activity。 我有3个标签。第二个和第三个选项卡使用相同的Fragment-Class。以下是标签的摘要:

在AccountActivity中

@Override
        public Fragment getItem(int position) {
            Fragment fragment = null;
            Bundle args = new Bundle();
            switch (position) {
            case POSITION_OVERVIEW:
                fragment = new OverviewSectionFragment();
                break;
            case POSITION_INCOME:
                args.putString("flag", TransactionSectionFragment.INCOME);
                fragment = new TransactionSectionFragment();
                fragment.setArguments(args);
                break;
            case POSITION_OUTGO:
                args.putString("flag", TransactionSectionFragment.OUTGO);
                fragment = new TransactionSectionFragment();
                fragment.setArguments(args);
                break;
            }
            return fragment;
        }
片段本身看起来像这样:

public class TransactionSectionFragment extends Fragment {

    OnDataChangedListener mCallback;

    public interface OnDataChangedListener {
        public void onDataChanged(int rnd);
    }

    // Private variables for IncomeSectionFragment
    private FinanceDataSource datasource;
    private ListView transactionList;
    private CustomFinanceListAdapter adapter;
    private String flag;
    private Button newTran;

    // public constants
    public static final String INCOME = "i";
    public static final String OUTGO = "o";

    // Variables for Contextmenu
    private static final int DETAILS_OPTION = Menu.FIRST;
    private static final int DELETE_OPTION = DETAILS_OPTION + 1;

    public TransactionSectionFragment() {

    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallback = (OnDataChangedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnDataChangedListener");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(
                R.layout.fragment_account_transactions, container, false);
        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        newTran = (Button) getView().findViewById(R.id.new_entry_btn);
        transactionList = (ListView) this.getView().findViewById(
                R.id.transactionlist);
        flag = getArguments().getString("flag");

        datasource = new FinanceDataSource(getActivity());
        datasource.open();
        updateList();
        registerForContextMenu(transactionList);

        transactionList
                .setOnItemClickListener(new AdapterView.OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> arg0, View arg1,
                            int position, long arg3) {
                        Transaction tran = (Transaction) transactionList
                                .getItemAtPosition(position);
                        showTransactionDetails(tran);
                    }

                });

        newTran.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                datasource.insertSomeTransactions();
                updateList();
            }
        });
    }

    @Override
    public void onResume() {
        datasource.open();
        super.onResume();
    }

    @Override
    public void onPause() {
        datasource.close();
        super.onPause();
    }

    private void showTransactionDetails(Transaction tran) {

    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        if (v.getId() == R.id.transactionlist) {
            menu.setHeaderTitle("Optionen ");
            menu.add(Menu.NONE, DETAILS_OPTION, 0, "Details");
            menu.add(Menu.NONE, DELETE_OPTION, 1, "Eintrag löschen");
        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
                .getMenuInfo();
        Transaction tran = (Transaction) transactionList
                .getItemAtPosition(info.position);
        switch (item.getItemId()) {
        case DETAILS_OPTION:
            showMsg(tran.getID() + "");
            break;
        case DELETE_OPTION:
            try {
                datasource.deleteTransaction(tran);
                updateList();
                showMsg("Entry deleted!");
            } catch (Exception e) {
                Log.i("Exception", e.getMessage());
            }
            break;
        }
        return true;
    }

    // Show Toast
    private void showMsg(String message) {
        Toast msg = Toast.makeText(getActivity(), message, Toast.LENGTH_LONG);
        msg.show();
    }

    private void updateList() {
        adapter = new CustomFinanceListAdapter(
                datasource.getAllTransactions(flag), getActivity());
        transactionList.setAdapter(adapter);
        mCallback.onDataChanged(new Random().nextInt());
    }
}

现在问题: 表示收入的第一个片段填充了标记为&#34; i&#34;的sqlite数据库中的数据。第二个片段被标记为&#34; o&#34;。这很好用。列表视图中的每个条目代表一个交易---&gt;看到这里:

public class Transaction {
    // private variables
    int id;
    String date;
    double value;
    String desc;
    String flag;

    // Empty constructor
    public Transaction() {

    }

    // constructor
    public Transaction(String date, double value, String desc, String flag) {
        this.date = date;
        this.value = value;
        this.desc = desc;
        this.flag = flag;
    }

    // constructor
    public Transaction(int id, String date, double value, String desc,
            String flag) {
        this.id = id;
        this.date = date;
        this.value = value;
        this.desc = desc;
        this.flag = flag;
    }

    // get name
    public int getID() {
        return this.id;
    }

    // get name
    public String getDate() {
        return this.date;
    }

    // set name
    public void setDate(String date) {
        this.date = date;
    }

    // get value
    public double getValue() {
        return this.value;
    }

    // set value
    public void setValue(double value) {
        this.value = value;
    }

    // get description
    public String getDesc() {
        return this.desc;
    }

    // set description
    public void setDesc(String desc) {
        this.desc = desc;
    }

    // get flag
    public String getFlag() {
        return this.flag;
    }

    // set flag
    public void setFlag(String flag) {
        this.flag = flag;
    }

    @Override
    public String toString() {
        return this.getDesc();
    }
}

通过长按list-item,我获得了Transaction的ID,它应该与数据库中的ID相同(autoincrementy主键等)。所以它应该是独一无二的。但是,outgo-list上的第一项与收入列表中的第一项具有相同的ID。通过从收入列表中删除一个项目,结果列表中的最后一项获得了一个outofboundexception,因为理论上应该有一个少于显示的项目。但是结果列表并没有像收入那样刷新自己,更像是一个&#34;副本&#34;不同价值的收入。

希望你能解决我的问题.... 如果您需要更多代码,请告诉我=)

编辑1: 这是创建表的SQL语句:

USERS_TABLE_CREATE = "CREATE TABLE "
            + TABLE_FINANCES + " (" + COLUMN_ID
            + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + COLUMN_DATE
            + " DATETIME NOT NULL," + COLUMN_VALUE + " REAL NOT NULL," + COLUMN_DESC
            + " NVARCHAR(255)," + COLUMN_FLAG  + " NVARCHAR(1) NOT NULL);";

数据集本身看起来像:

(id,date,value,description,flag)==&gt; ex1:(2,23.08.2013,33.33,&#34; tip&#34;,&#34; i&#34;)收入数据集和ex2:(3,23.08.2013,12.12,&#34;门票&对于结果数据集

,#34;,&#34; o&#34;)

现在有些图片: 带有第一个条目的getID()的收入屏幕 - &gt; http://i.imgur.com/kfCkjGr.png 带有第一个条目的getID()的outgo屏幕 - &gt; http://i.imgur.com/tOdoSqb.png

编辑2: 我帮助解决了这个问题: Wrong fragment in ViewPager receives onContextItemSelected call

你必须使用this包装onContextItemSelected Call,因为fragmentmanager将第一个可用片段返回true,用于contextmenu,而不是你实际使用的那个

if (getUserVisibleHint()) {
    // Handle menu events and return true
} else
    return false; // Pass the event to the next fragment
}

0 个答案:

没有答案