2013-03-06 5 views
1

데이터베이스에 대한 항목을 볼 수있는 어댑터가있는 사용자 지정 ListView가 있습니다. 목록의 첫 번째 항목을 클릭하려고 시도 할 때까지 ListView의 모든 항목이 올바르게 작동합니다. 클릭하면 항목을 편집기에로드해야합니다. 어떤 이유로 든, 어떤 항목이 클릭되었는지에 관계없이 목록의 첫 번째 항목이 편집기에로드됩니다. 여기android listview setonclicklistener는 첫 번째보기 만 선택합니다.

public class MainActivity extends Activity { 

public static final String KEY_ID = "listviewId"; 
public static final String KEY_SHORT = "projectShortTextView"; 
public static final String KEY_FULL = "projectFullTextView"; 
public static final String KEY_HOURS = "listviewHoursTV"; 
public static final String KEY_PROID = "projectIdTV"; 
private SQLiteDatabase db; 
private TimesheetDatabaseHelper dbHelp = new TimesheetDatabaseHelper(this); 
/** Gets a valid calendar instance for use */ 
final Calendar c = Calendar.getInstance(); 
/** Strings for formatting the date's for use */ 
public String dateViewForm = "EEE MM/dd/yyyy"; 
public String dateForm = "MM/dd/yyyy"; 
public String timeForm = "HH:mm"; 
/** Strings to store formated calendar outputs */ 
public String date, dateView; 
/** Prepares buttons and EditText for use */ 
public Button minusButton, plusButton, quickAdd; 
public EditText dateEditText; 
public ListView list; 
TimestampAdapter adapter; 
SimpleDateFormat formDateView = new SimpleDateFormat(dateViewForm, Locale.US); 
SimpleDateFormat formDate = new SimpleDateFormat(dateForm, Locale.US); 
SimpleDateFormat formTime = new SimpleDateFormat(timeForm, Locale.US); 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    BugSenseHandler.initAndStartSession(MainActivity.this, "8b04fe90"); 
    setContentView(R.layout.activity_main); 

    try { 
     updateCheck(); 
    } catch (NameNotFoundException e1) { 
     e1.printStackTrace(); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
    } 


    /** Method to get todays date and display it in the proper places */ 
    date = initialDates(); 

    getDailyTimestamps(date); 

    /** 
    * Implements the Minus Button with OnCLickListener and 
    * calls the minusButtonHandler if called */ 
    minusButton = (Button)findViewById(R.id.minusButton); 
    minusButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      try { 
       date = minusButtonHandler(); 
       getDailyTimestamps(date); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    /** 
    * Implements the Plus Button with OnCLickListener and 
    * calls the plusButtonHandler if called */ 
    plusButton = (Button)findViewById(R.id.plusButton); 
    plusButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      try { 
       date = plusButtonHandler(); 
       getDailyTimestamps(date); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    quickAdd = (Button)findViewById(R.id.quickAddButton); 
    quickAdd.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      quickAddHandler(v); 
      getDailyTimestamps(date); 
     } 
    }); 
} 

@SuppressWarnings("deprecation") 
private void updateCheck() throws NameNotFoundException, IOException, InterruptedException, ExecutionException { 
    Log.d("Checking for updates", "true"); 
    String urlVersion; 
    UpdateCheck check = new UpdateCheck(); 
    urlVersion = check.execute().get(); 

    Log.d("urlVerion", urlVersion); 

    PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); 
    String packageVersion = pInfo.versionName; 

    Log.d("Package Version", packageVersion); 

    if (!urlVersion.equals(packageVersion)) { 
     AlertDialog alert = new AlertDialog.Builder(this).create(); 
     alert.setTitle("Version Check"); 
     alert.setMessage("You're version is out of date. Please visit " 
       + "www.ubundude.com/p/beta.html to update to the latest version."); 

     alert.setButton("OK", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
      } 
    }); 
     alert.show(); 
    } 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    getDailyTimestamps(date); 
} 

private void getDailyTimestamps(String date) { 
    ArrayList<HashMap<String, String>> stampList = new ArrayList<HashMap<String, String>>(); 

    /** Open the database table for reading and writing */ 
    db = dbHelp.getReadableDatabase(); 

    String getTimestamps = "select ti._id, pr.name, pr.shortcode, ti.hours, ti.project " 
      + "from timestamp ti inner join projects pr " 
      + "where ti.project = pr._id and ti.date_in = '" + date + "'"; 

    Cursor cu = db.rawQuery(getTimestamps, null); 

    if(cu != null && cu.getCount() > 0){ 
     cu.moveToFirst(); 

     do { 
      HashMap<String, String> map = new HashMap<String, String>(); 
      map.put(KEY_ID, Integer.toString(cu.getInt(0))); 
      map.put(KEY_SHORT, cu.getString(1)); 
      map.put(KEY_FULL, cu.getString(2)); 
      map.put(KEY_HOURS, cu.getString(3)); 
      map.put(KEY_PROID, Integer.toString(cu.getInt(4))); 

      stampList.add(map); 

     } while(cu.moveToNext()); 
    } 

    cu.close(); 
    db.close(); 

    list = (ListView)findViewById(R.id.timestampListView); 

    adapter = new TimestampAdapter(this, stampList); 
    list.setAdapter(adapter); 

    list.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 
      Log.d("ListView On Click", "Position: " + position); 
      TextView idTV = (TextView)findViewById(R.id.listviewId); 
      TextView proIdTV = (TextView)findViewById(R.id.projectIdTV); 
      TextView full = (TextView)findViewById(R.id.projectShortTextView); 
      String test = full.getText().toString(); 
      Log.d("Listview", "Project Name: " + test); 
      int timeId = Integer.parseInt(idTV.getText().toString()); 
      Log.d("Listview", "Timestamp ID: " + timeId); 
      int proId = Integer.parseInt(proIdTV.getText().toString()); 
      Log.d("Listview", "Project ID: " + proId); 
      Intent intent = new Intent(MainActivity.this, TimestampEditorActivity.class); 
      intent.putExtra("TIMESTAMP_ID", timeId); 
      intent.putExtra("PROJECT_ID", proId); 
      startActivity(intent); 
     } 
    }); 
} 

private String initialDates() { 
    dateView = formDateView.format(c.getTime()); 
    date = formDate.format(c.getTime()); 

    /** Sets the text in the dateEditText to the current date */ 
    dateEditText = (EditText)findViewById(R.id.dateEditText); 
    dateEditText.setText(dateView, TextView.BufferType.NORMAL); 

    return date; 
} 

/** Gets the next day and displays to dateEditText 
* @throws ParseException */ 
private String plusButtonHandler() throws ParseException { 

    c.setTime(formDateView.parse(dateView)); 
    c.add(Calendar.DAY_OF_MONTH, 1); 

    dateView = formDateView.format(c.getTime()); 
    date = formDate.format(c.getTime()); 

    dateEditText = (EditText)findViewById(R.id.dateEditText); 
    dateEditText.setText(dateView, TextView.BufferType.NORMAL); 

    return date; 
} 

    /** Gets the previous day and displays to dateEditText 
    * @throws ParseException */ 
private String minusButtonHandler() throws ParseException { 
    c.setTime(formDateView.parse(dateView)); 
    c.add(Calendar.DAY_OF_MONTH, -1); 

    dateView = formDateView.format(c.getTime()); 
    date = formDate.format(c.getTime()); 

    dateEditText = (EditText)findViewById(R.id.dateEditText); 
    dateEditText.setText(dateView, TextView.BufferType.NORMAL); 

    return date; 
} 

/** 
* Intent to move to TimestampEditorActivity 
* 
* @param view Gets the current view context to pass with the intent 
*/ 
public void addNewHandler(View view) { 
    Intent intent = new Intent(this, TimestampEditorActivity.class); 
    startActivity(intent); 
} 

/** 
* Get current date and time and place them into Timestamp table as generic entry 
* 
* @param view 
* @throws SQLException 
*/ 
public void quickAddHandler(View view) throws SQLException { 
    String timeIn, timeOut, dateIn, dateOut; 
    int project = 1; //Will get from Default project in settings 
    timeIn = formTime.format(c.getTime()); 
    timeOut = timeIn; 
    dateIn = formDate.format(c.getTime()); 
    dateOut = dateIn; 
    db = dbHelp.getWritableDatabase(); 
    String insertSQL = "insert into timestamp (date_in, time_in, date_out, time_out, hours, project) " + 
      "values('" + dateIn + "', '" + timeIn + "', '" + dateOut + 
      "', '" + timeOut + "', 0, '" + project + "')"; 
    try { 
     db.execSQL(insertSQL); 
    } catch(Exception e) { 
     Log.d("save Fail", e.getLocalizedMessage(), e.fillInStackTrace()); 
    } 
    db.close(); 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

} 

ListView에 대한 XML된다 : 여기

<TextView 
     android:id="@+id/projectShortTextView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:text="@string/defaultText" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

    <TextView 
     android:id="@+id/projectFullTextView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_below="@+id/projectShortTextView" 
     android:text="@string/defaultText" 
     android:textAppearance="?android:attr/textAppearanceSmall" /> 

    <TextView 
     android:id="@+id/listviewId" 
     android:visibility="invisible" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_toRightOf="@+id/projectShortTextView" 
     android:text="@string/defaultInt" /> 

    <Button 
     android:id="@+id/listviewEditButton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerVertical="true" 
     android:layout_toLeftOf="@+id/listviewHoursTV" 
     android:background="@drawable/edit" 
     android:focusable="false" /> 

    <TextView 
     android:id="@+id/listviewHoursTV" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_centerVertical="true" 
     android:text="@string/defaultTime" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

    <TextView 
     android:id="@+id/projectIdTV" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/projectFullTextView" 
     android:layout_toRightOf="@+id/listviewId" 
     android:text="@string/defaultInt" 
     android:visibility="invisible" /> 

</RelativeLayout> 

그리고 어댑터가됩니다 다음은 ListView에 대한 활동 코드가 공용 클래스 TimestampAdapter가 BaseAdapter를 확장 { 개인 활동 활동 ; private ArrayList> data; 개인 정적 LayoutInflater inflater = null;

public TimestampAdapter(Activity a, ArrayList<HashMap<String, String>> d) { 
    activity = a; 
    data = d; 
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

public int getCount() { 
    return data.size(); 
} 

public Object getItem(int position) { 
    return data.get(position); 
} 

public long getItemId(int position) { 
    return position; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View vi = convertView; 
    if(convertView==null) 
     vi = inflater.inflate(R.layout.listview_timestamp, null); 

    TextView projectShort = (TextView)vi.findViewById(R.id.projectShortTextView); 
    TextView projectFull = (TextView)vi.findViewById(R.id.projectFullTextView); 
    TextView stampId = (TextView)vi.findViewById(R.id.listviewId); 
    TextView hoursEdit = (TextView)vi.findViewById(R.id.listviewHoursTV); 
    TextView projectId = (TextView)vi.findViewById(R.id.projectIdTV); 

    HashMap<String, String> timestamp = new HashMap<String, String>(); 
    timestamp = data.get(position); 

    stampId.setText(timestamp.get(MainActivity.KEY_ID)); 
    projectShort.setText(timestamp.get(MainActivity.KEY_SHORT)); 
    projectFull.setText(timestamp.get(MainActivity.KEY_FULL)); 
    hoursEdit.setText(timestamp.get(MainActivity.KEY_HOURS) + " hrs"); 
    projectId.setText(timestamp.get(MainActivity.KEY_PROID)); 

return vi; 
} 

}  

위의 코드의 디버그 라인은 각 행의 적절한 위치를 클릭 보여 주지만, 첫 번째 행의 정보의 id의 최대 보여줄 수있는 유일한 사람입니다. 그리고 이것은 첫 번째 행만 편집기에로드되는 것과 일치합니다.

+0

HashMap <String,String> currentMap = stampList.get(position); 

을 교체?. 어댑터에서 초기화해야합니다. 완전한 활동과 어댑터 코드를 보여줄 수 있습니까? –

+0

주 코드와 어댑터를 모두 추가했습니다 – ubundude

답변

2

당신의 문제는 아마이 라인에있다 :리스트 뷰의 행의 Activity, 하지의 레이아웃에서 이러한 견해를 찾는

TextView idTV = (TextView)findViewById(R.id.listviewId); 
TextView proIdTV = (TextView)findViewById(R.id.projectIdTV); 
TextView full = (TextView)findViewById(R.id.projectShortTextView); 

. 이러한 IDS는 또한 ListView에 중복되는 경우 StampList이 모든 데이터를 포함하는 복합 객체의 목록 인 경우,

view.findViewById(R.id.yourId); 

를 통해 전체 행에 액세스하면 뷰의 발견을 건너 뛰고 어댑터를 사용하거나 AdapterView는 객체에 접근합니다.

편집 : 당신은의 HashMap을 사용하는이 쉽게해야한다 :

@Override 
public void onItemClick(AdapterView<?> parent, View view, 
         int position, long id) { 
    HashMap <String,String> currentMap = stampList.get(position); 
    Intent intent = new Intent(MainActivity.this, TimestampEditorActivity.class); 
    intent.putExtra("TIMESTAMP_ID", currentMap.get(MainActivity.KEY_ID)); 
    intent.putExtra("PROJECT_ID", currentMap.get(MainActivity.KEY_PROID)); 
    startActivity(intent); 
} 

그냥 final으로 stampList를 선언해야합니다. 당신은 지정하지 않는 경우는 OnClickListener를에서보기 인스턴스 (등 텍스트 뷰를) 초기화하는 이유는 무엇입니까 또는 stampListfinal로는

HashMap <String,String> currentMap = (HashMap<String,String>)parent.getItemAtPosition(position); 
+1

원래 답변을 읽은 후 동일한 결론을 얻었습니다. 이제 작동 중입니다. 내 대답은 약간 달랐다. 빠른 답장을 보내 주셔서 감사합니다. – ubundude

+0

@ user2104186 빠른 피드백을 보내 주셔서 감사합니다 .-) –

관련 문제