2

I'm creating a small Financecontrol-App. Now I'm facing a problem i don't think I can handle without hitting my phone =D

I got an Activity with a ViewPager created from Android-Template. I got 3 tabs. The second and third tabs use the same Fragment-Class. Here is the snippet for the tabs:

in 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;
        }

the Fragment itself looks like this:

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());
    }
}

and now the problem: the first Fragment which represents the income is filled with data from a sqlite database flagged with an "i". the second Fragment is outgo flagged with an "o". This works pretty fine. ervery entry in the listview represents a Transaction ---> see here:

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();
    }
}

by long-clicking a list-item i get the ID of the Transaction which should be the same like it has in the database (autoincrementy primary key etc.). so it should be unique. but the first item on outgo-list has the same id as the first item on income-list. by deleting an item from income-list the last item in the outcome list gets a outofboundexception because theoretically there should have been one less than displayed. but the outcome-list does not refresh itself like income and is more like a "copy" of income with different values.

hope you get my problem.... if you need more code please tell me =)

EDIT 1: Here is the SQL-Statement creating the table:

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);";

Datasets itself look like:

(id, date, value, description, flag) ==> ex1: (2, 23.08.2013, 33.33, "tip", "i") for an income dataset and ex2: (3, 23.08.2013, 12.12, "tickets", "o") for an outcome-dataset

Now some pictures: income screen with getID() of first entry --> https://i.stack.imgur.com/lCeeD.png outgo screen with getID() of first entry --> https://i.stack.imgur.com/6gdUQ.png

EDIT 2: I solved the problem with help from: Wrong fragment in ViewPager receives onContextItemSelected call

you have to wrap the onContextItemSelected Call with this because the fragmentmanager takes the first availabe fragment returning true for contextmenu and not the one you're actually on

if (getUserVisibleHint()) {
    // Handle menu events and return true
} else
    return false; // Pass the event to the next fragment
}
Community
  • 1
  • 1
MKAI
  • 64
  • 6
  • I do not get the problem. Whats the difference in data when using the flag? Do you expect different data, or twice the same? – Stefan de Bruijn Aug 23 '13 at 07:41
  • Hi. I will provide some more information on the table itself. I HAVE different data, which is correctly displayed in both listviews. But obviously the both fragments or listviews are "connected" to each other. a change in one has influence on the other. and i dont get why that happens. – MKAI Aug 23 '13 at 07:46
  • It looks like the problem is the ContextMenu .... I think the menu only refers to the list at the first fragment .... – MKAI Aug 23 '13 at 11:51

0 Answers0